diff --git a/src/storage-blob-preview/HISTORY.rst b/src/storage-blob-preview/HISTORY.rst
index c75222a6a1d..50ed7e84387 100644
--- a/src/storage-blob-preview/HISTORY.rst
+++ b/src/storage-blob-preview/HISTORY.rst
@@ -2,6 +2,10 @@
Release History
===============
+0.6.2
+++++++
+* `az storage blob filter`: Add `--container-name` to support filter blobs in specific container
+
0.6.1
++++++
* `az storage blob immutability-policy set/delete`: Extend/Lock/Unlock/Delete blob's immutability policy
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/__init__.py
index 8707dbdcebb..9217d8af0fe 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/__init__.py
+++ b/src/storage-blob-preview/azext_storage_blob_preview/__init__.py
@@ -14,7 +14,7 @@
class StorageCommandsLoader(AzCommandsLoader):
def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
- register_resource_type('latest', CUSTOM_DATA_STORAGE_BLOB, '2020-10-02')
+ register_resource_type('latest', CUSTOM_DATA_STORAGE_BLOB, '2021-04-10')
storage_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.storage.custom#{}')
super(StorageCommandsLoader, self).__init__(cli_ctx=cli_ctx,
resource_type=CUSTOM_DATA_STORAGE_BLOB,
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/_help.py b/src/storage-blob-preview/azext_storage_blob_preview/_help.py
index 84132a80d3a..c8b615d0dcd 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/_help.py
+++ b/src/storage-blob-preview/azext_storage_blob_preview/_help.py
@@ -76,15 +76,11 @@
helps['storage blob filter'] = """
type: command
short-summary: List blobs across all containers whose tags match a given search expression.
-long-summary: >
- Filter blobs searches across all containers within a storage account but can be scoped within the expression to
- a single container.
parameters:
- name: --tag-filter
short-summary: >
The expression to find blobs whose tags matches the specified condition.
eg. ""yourtagname"='firsttag' and "yourtagname2"='secondtag'"
- To specify a container, eg. "@container='containerName' and "Name"='C'"
"""
helps['storage blob list'] = """
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/_params.py b/src/storage-blob-preview/azext_storage_blob_preview/_params.py
index e1a6301b823..3d4dc6a9959 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/_params.py
+++ b/src/storage-blob-preview/azext_storage_blob_preview/_params.py
@@ -264,6 +264,8 @@ def load_arguments(self, _): # pylint: disable=too-many-locals, too-many-statem
with self.argument_context('storage blob filter') as c:
c.argument('filter_expression', options_list=['--tag-filter'])
+ c.argument('container_name', container_name_type,
+ help='Used when you want to list blobs under a specified container')
with self.argument_context('storage blob generate-sas') as c:
from .completers import get_storage_acl_name_completion_list
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/commands.py b/src/storage-blob-preview/azext_storage_blob_preview/commands.py
index 9ec50fc59fe..eeec5e7f6d6 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/commands.py
+++ b/src/storage-blob-preview/azext_storage_blob_preview/commands.py
@@ -85,7 +85,7 @@ def get_custom_sdk(custom_module, client_factory, resource_type=ResourceType.DAT
with self.command_group('storage blob', blob_service_sdk, resource_type=CUSTOM_DATA_STORAGE_BLOB,
min_api='2019-12-12',
custom_command_type=blob_service_custom_sdk) as g:
- g.storage_command_oauth('filter', 'find_blobs_by_tags', is_preview=True)
+ g.storage_custom_command_oauth('filter', 'find_blobs_by_tags', is_preview=True)
blob_lease_client_sdk = CliCommandType(
operations_tmpl='azure.multiapi.storagev2.blob._lease#BlobLeaseClient.{}',
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/operations/blob.py b/src/storage-blob-preview/azext_storage_blob_preview/operations/blob.py
index 5bf8ce19ae7..1d5881164be 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/operations/blob.py
+++ b/src/storage-blob-preview/azext_storage_blob_preview/operations/blob.py
@@ -720,3 +720,9 @@ def query_blob(cmd, client, query_expression, input_config=None, output_config=N
return None
return reader.readall().decode("utf-8")
+
+
+def find_blobs_by_tags(client, filter_expression, container_name=None):
+ if container_name:
+ client = client.get_container_client(container_name)
+ return client.find_blobs_by_tags(filter_expression=filter_expression)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_tags_scenario.yaml b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_tags_scenario.yaml
index 1b13abe23fa..822e4b73103 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_tags_scenario.yaml
+++ b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_tags_scenario.yaml
@@ -2,16 +2,24 @@ interactions:
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container create
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:38:20 GMT
+ - Mon, 24 Oct 2022 06:05:06 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003?restype=container
response:
@@ -21,31 +29,39 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:38:20 GMT
+ - Mon, 24 Oct 2022 06:05:07 GMT
etag:
- - '"0x8DA20FDA5F36E2A"'
+ - '"0x8DAB585B3F003AD"'
last-modified:
- - Mon, 18 Apr 2022 05:38:20 GMT
+ - Mon, 24 Oct 2022 06:05:08 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 201
message: Created
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container create
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:38:21 GMT
+ - Mon, 24 Oct 2022 06:05:07 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont2000004?restype=container
response:
@@ -55,15 +71,15 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:38:22 GMT
+ - Mon, 24 Oct 2022 06:05:08 GMT
etag:
- - '"0x8DA20FDA6E08956"'
+ - '"0x8DAB585B4CE520D"'
last-modified:
- - Mon, 18 Apr 2022 05:38:22 GMT
+ - Mon, 24 Oct 2022 06:05:09 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 201
message: Created
@@ -87,15 +103,15 @@ interactions:
ParameterSetName:
- -c -f -n --tags --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-blob-type:
- BlockBlob
x-ms-date:
- - Mon, 18 Apr 2022 05:38:23 GMT
+ - Mon, 24 Oct 2022 06:05:09 GMT
x-ms-tags:
- date=2020-01-01&category=test
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005
response:
@@ -107,11 +123,11 @@ interactions:
content-md5:
- DfvoqkwgtS4bi/PLbL3xkw==
date:
- - Mon, 18 Apr 2022 05:38:24 GMT
+ - Mon, 24 Oct 2022 06:05:11 GMT
etag:
- - '"0x8DA20FDA852192A"'
+ - '"0x8DAB585B646C1C7"'
last-modified:
- - Mon, 18 Apr 2022 05:38:24 GMT
+ - Mon, 24 Oct 2022 06:05:11 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-content-crc64:
@@ -119,7 +135,7 @@ interactions:
x-ms-request-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 201
message: Created
@@ -137,19 +153,19 @@ interactions:
ParameterSetName:
- -c --include --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:38:55 GMT
+ - Mon, 24 Oct 2022 06:05:41 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003?restype=container&comp=list&maxresults=5000&include=tags
response:
body:
string: "\uFEFF5000blob000005Mon,
- 18 Apr 2022 05:38:24 GMTMon, 18 Apr 2022 05:38:24
- GMT0x8DA20FDA852192A131072application/octet-streamMon, 24 Oct 2022 06:05:11
+ GMT0x8DAB585B646C1C7131072application/octet-streamDfvoqkwgtS4bi/PLbL3xkw==BlockBlobHottrueunlockedavailabletrue2categorytestdate2020-01-01"
@@ -157,13 +173,13 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:38:55 GMT
+ - Mon, 24 Oct 2022 06:05:42 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -181,11 +197,11 @@ interactions:
ParameterSetName:
- -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:38:59 GMT
+ - Mon, 24 Oct 2022 06:05:43 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=tags
response:
@@ -197,11 +213,11 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:38:59 GMT
+ - Mon, 24 Oct 2022 06:05:44 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -221,15 +237,15 @@ interactions:
ParameterSetName:
- --source-blob --source-container -c -b --tags --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.10.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-copy-source:
- - https://blobtag7cecw7sf6hbq72peq.blob.core.windows.net/cont126k356pvuzwcxq4gwkt/blobr5yl5zh6jdy7ycxdg7cy
+ - https://blobtagrfdgx6wf7ljxth3ik.blob.core.windows.net/cont1urijtimap7657pj2y4s/blobwm3b4jnvm4us4yxdwah4
x-ms-date:
- - Mon, 18 Apr 2022 05:39:01 GMT
+ - Mon, 24 Oct 2022 06:05:44 GMT
x-ms-tags:
- number=1
x-ms-version:
- - '2021-04-10'
+ - '2021-06-08'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont2000004/blob000006
response:
@@ -239,19 +255,19 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:01 GMT
+ - Mon, 24 Oct 2022 06:05:46 GMT
etag:
- - '"0x8DA20FDBE730DC5"'
+ - '"0x8DAB585CAE6FD0C"'
last-modified:
- - Mon, 18 Apr 2022 05:39:02 GMT
+ - Mon, 24 Oct 2022 06:05:46 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-copy-id:
- - af5e0626-3819-4fc3-b515-a8bcffdd8446
+ - 96ed856b-21b8-4e1b-98d6-6fc87e3e37f8
x-ms-copy-status:
- success
x-ms-version:
- - '2021-04-10'
+ - '2021-06-08'
status:
code: 202
message: Accepted
@@ -269,11 +285,11 @@ interactions:
ParameterSetName:
- -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:02 GMT
+ - Mon, 24 Oct 2022 06:05:46 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont2000004/blob000006?comp=tags
response:
@@ -285,11 +301,11 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:03 GMT
+ - Mon, 24 Oct 2022 06:05:47 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -307,19 +323,19 @@ interactions:
ParameterSetName:
- -c --include --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:04 GMT
+ - Mon, 24 Oct 2022 06:05:47 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont2000004?restype=container&comp=list&maxresults=5000&include=tags
response:
body:
string: "\uFEFF5000blob000006Mon,
- 18 Apr 2022 05:39:02 GMTMon, 18 Apr 2022 05:39:02
- GMT0x8DA20FDBE730DC5131072application/octet-streamMon, 24 Oct 2022 06:05:46
+ GMT0x8DAB585CAE6FD0C131072application/octet-streamDfvoqkwgtS4bi/PLbL3xkw==BlockBlobHottrueunlockedavailabletrue1number1"
@@ -327,13 +343,13 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:05 GMT
+ - Mon, 24 Oct 2022 06:05:49 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -357,11 +373,11 @@ interactions:
ParameterSetName:
- -n -c --tags --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:06 GMT
+ - Mon, 24 Oct 2022 06:05:49 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=tags
response:
@@ -369,11 +385,11 @@ interactions:
string: ''
headers:
date:
- - Mon, 18 Apr 2022 05:39:07 GMT
+ - Mon, 24 Oct 2022 06:05:51 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 204
message: No Content
@@ -391,11 +407,11 @@ interactions:
ParameterSetName:
- -n -c --tags --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:08 GMT
+ - Mon, 24 Oct 2022 06:05:51 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=tags
response:
@@ -407,11 +423,11 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:07 GMT
+ - Mon, 24 Oct 2022 06:05:51 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -429,11 +445,11 @@ interactions:
ParameterSetName:
- -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:09 GMT
+ - Mon, 24 Oct 2022 06:05:51 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=tags
response:
@@ -445,11 +461,11 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:09 GMT
+ - Mon, 24 Oct 2022 06:05:53 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -467,11 +483,11 @@ interactions:
ParameterSetName:
- --tag-filter --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:11 GMT
+ - Mon, 24 Oct 2022 06:05:53 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/?comp=blobs&where=test%3D%27tag%27
response:
@@ -482,13 +498,52 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:11 GMT
+ - Mon, 24 Oct 2022 06:05:55 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ transfer-encoding:
+ - chunked
+ x-ms-version:
+ - '2021-04-10'
+ status:
+ code: 200
+ message: OK
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage blob filter
+ Connection:
+ - keep-alive
+ ParameterSetName:
+ - --tag-filter -c --account-name --account-key
+ User-Agent:
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
+ x-ms-date:
+ - Mon, 24 Oct 2022 06:05:54 GMT
+ x-ms-version:
+ - '2021-04-10'
+ method: GET
+ uri: https://blobtag000002.blob.core.windows.net/cont1000003?restype=container&comp=blobs&where=test%3D%27tag%27
+ response:
+ body:
+ string: "\uFEFF\ntest='tag'blob000005cont1000003testtag"
+ headers:
+ content-type:
+ - application/xml
+ date:
+ - Mon, 24 Oct 2022 06:05:55 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -509,15 +564,15 @@ interactions:
- --source-blob --source-container -c -b --source-tags-condition --account-name
--account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.10.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-copy-source:
- - https://blobtag7cecw7sf6hbq72peq.blob.core.windows.net/cont126k356pvuzwcxq4gwkt/blobr5yl5zh6jdy7ycxdg7cy
+ - https://blobtagrfdgx6wf7ljxth3ik.blob.core.windows.net/cont1urijtimap7657pj2y4s/blobwm3b4jnvm4us4yxdwah4
x-ms-date:
- - Mon, 18 Apr 2022 05:39:13 GMT
+ - Mon, 24 Oct 2022 06:05:56 GMT
x-ms-source-if-tags:
- test='tag'
x-ms-version:
- - '2021-04-10'
+ - '2021-06-08'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont2000004/blob000006
response:
@@ -527,19 +582,19 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:14 GMT
+ - Mon, 24 Oct 2022 06:05:57 GMT
etag:
- - '"0x8DA20FDC5B4D22F"'
+ - '"0x8DAB585D1F75187"'
last-modified:
- - Mon, 18 Apr 2022 05:39:14 GMT
+ - Mon, 24 Oct 2022 06:05:58 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-copy-id:
- - cbb6281b-61d2-4f0c-8368-b895f32d27e3
+ - f18e0e53-1844-4dd4-832b-5d81f59a2afd
x-ms-copy-status:
- success
x-ms-version:
- - '2021-04-10'
+ - '2021-06-08'
status:
code: 202
message: Accepted
@@ -561,17 +616,17 @@ interactions:
ParameterSetName:
- -n -c --tags-condition -f --tags --overwrite --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-blob-type:
- BlockBlob
x-ms-date:
- - Mon, 18 Apr 2022 05:39:15 GMT
+ - Mon, 24 Oct 2022 06:05:58 GMT
x-ms-if-tags:
- test='tag'
x-ms-tags:
- date=2020-01-01&category=test
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005
response:
@@ -583,11 +638,11 @@ interactions:
content-md5:
- DfvoqkwgtS4bi/PLbL3xkw==
date:
- - Mon, 18 Apr 2022 05:39:16 GMT
+ - Mon, 24 Oct 2022 06:05:59 GMT
etag:
- - '"0x8DA20FDC7794AA2"'
+ - '"0x8DAB585D3658F87"'
last-modified:
- - Mon, 18 Apr 2022 05:39:17 GMT
+ - Mon, 24 Oct 2022 06:06:00 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-content-crc64:
@@ -595,7 +650,7 @@ interactions:
x-ms-request-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 201
message: Created
@@ -615,15 +670,15 @@ interactions:
ParameterSetName:
- -n -c --tags-condition --metadata --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:17 GMT
+ - Mon, 24 Oct 2022 06:06:00 GMT
x-ms-if-tags:
- category='test'
x-ms-meta-a:
- b
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=metadata
response:
@@ -633,17 +688,17 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:18 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -661,13 +716,13 @@ interactions:
ParameterSetName:
- -n -c --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:20 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
x-ms-if-tags:
- category='test'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: HEAD
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005
response:
@@ -683,11 +738,11 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:39:20 GMT
+ - Mon, 24 Oct 2022 06:06:04 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
@@ -697,7 +752,7 @@ interactions:
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:38:24 GMT
+ - Mon, 24 Oct 2022 06:05:11 GMT
x-ms-lease-state:
- available
x-ms-lease-status:
@@ -709,7 +764,7 @@ interactions:
x-ms-tag-count:
- '2'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -730,9 +785,9 @@ interactions:
- --lease-duration -b -c --proposed-lease-id --tags-condition --account-name
--account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:21 GMT
+ - Mon, 24 Oct 2022 06:06:05 GMT
x-ms-if-tags:
- category='test'
x-ms-lease-action:
@@ -742,7 +797,7 @@ interactions:
x-ms-proposed-lease-id:
- abcdabcd-abcd-abcd-abcd-abcdabcdabcd
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=lease
response:
@@ -752,17 +807,17 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:22 GMT
+ - Mon, 24 Oct 2022 06:06:07 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-lease-id:
- abcdabcd-abcd-abcd-abcd-abcdabcdabcd
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 201
message: Created
@@ -780,11 +835,11 @@ interactions:
ParameterSetName:
- -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:23 GMT
+ - Mon, 24 Oct 2022 06:06:06 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: HEAD
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005
response:
@@ -800,11 +855,11 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:39:24 GMT
+ - Mon, 24 Oct 2022 06:06:08 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
@@ -814,7 +869,7 @@ interactions:
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:38:24 GMT
+ - Mon, 24 Oct 2022 06:05:11 GMT
x-ms-lease-duration:
- fixed
x-ms-lease-state:
@@ -828,7 +883,7 @@ interactions:
x-ms-tag-count:
- '2'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -848,9 +903,9 @@ interactions:
ParameterSetName:
- -b -c --lease-id --proposed-lease-id --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:25 GMT
+ - Mon, 24 Oct 2022 06:06:08 GMT
x-ms-if-tags:
- category='test'
x-ms-lease-action:
@@ -860,7 +915,7 @@ interactions:
x-ms-proposed-lease-id:
- dcbadcba-dcba-dcba-dcba-dcbadcbadcba
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=lease
response:
@@ -870,17 +925,17 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:26 GMT
+ - Mon, 24 Oct 2022 06:06:10 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-lease-id:
- dcbadcba-dcba-dcba-dcba-dcbadcbadcba
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -900,9 +955,9 @@ interactions:
ParameterSetName:
- -b -c --lease-id --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:28 GMT
+ - Mon, 24 Oct 2022 06:06:10 GMT
x-ms-if-tags:
- category='test'
x-ms-lease-action:
@@ -910,7 +965,7 @@ interactions:
x-ms-lease-id:
- dcbadcba-dcba-dcba-dcba-dcbadcbadcba
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=lease
response:
@@ -920,17 +975,17 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:29 GMT
+ - Mon, 24 Oct 2022 06:06:13 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-lease-id:
- dcbadcba-dcba-dcba-dcba-dcbadcbadcba
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -948,11 +1003,11 @@ interactions:
ParameterSetName:
- -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:30 GMT
+ - Mon, 24 Oct 2022 06:06:12 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: HEAD
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005
response:
@@ -968,11 +1023,11 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:39:30 GMT
+ - Mon, 24 Oct 2022 06:06:14 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
@@ -982,7 +1037,7 @@ interactions:
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:38:24 GMT
+ - Mon, 24 Oct 2022 06:05:11 GMT
x-ms-lease-duration:
- fixed
x-ms-lease-state:
@@ -996,7 +1051,7 @@ interactions:
x-ms-tag-count:
- '2'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1016,9 +1071,9 @@ interactions:
ParameterSetName:
- -b -c --lease-break-period --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:32 GMT
+ - Mon, 24 Oct 2022 06:06:14 GMT
x-ms-if-tags:
- category='test'
x-ms-lease-action:
@@ -1026,7 +1081,7 @@ interactions:
x-ms-lease-break-period:
- '30'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=lease
response:
@@ -1036,17 +1091,17 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:32 GMT
+ - Mon, 24 Oct 2022 06:06:15 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-lease-time:
- '30'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 202
message: Accepted
@@ -1064,11 +1119,11 @@ interactions:
ParameterSetName:
- -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:33 GMT
+ - Mon, 24 Oct 2022 06:06:15 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: HEAD
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005
response:
@@ -1084,11 +1139,11 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:39:34 GMT
+ - Mon, 24 Oct 2022 06:06:17 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
@@ -1098,7 +1153,7 @@ interactions:
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:38:24 GMT
+ - Mon, 24 Oct 2022 06:05:11 GMT
x-ms-lease-state:
- breaking
x-ms-lease-status:
@@ -1110,7 +1165,7 @@ interactions:
x-ms-tag-count:
- '2'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1130,9 +1185,9 @@ interactions:
ParameterSetName:
- -b -c --lease-id --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:35 GMT
+ - Mon, 24 Oct 2022 06:06:17 GMT
x-ms-if-tags:
- category='test'
x-ms-lease-action:
@@ -1140,7 +1195,7 @@ interactions:
x-ms-lease-id:
- dcbadcba-dcba-dcba-dcba-dcbadcbadcba
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=lease
response:
@@ -1150,15 +1205,15 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:36 GMT
+ - Mon, 24 Oct 2022 06:06:19 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1176,11 +1231,11 @@ interactions:
ParameterSetName:
- -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:37 GMT
+ - Mon, 24 Oct 2022 06:06:19 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: HEAD
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005
response:
@@ -1196,11 +1251,11 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:39:38 GMT
+ - Mon, 24 Oct 2022 06:06:20 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
@@ -1210,7 +1265,7 @@ interactions:
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:38:24 GMT
+ - Mon, 24 Oct 2022 06:05:11 GMT
x-ms-lease-state:
- available
x-ms-lease-status:
@@ -1222,7 +1277,7 @@ interactions:
x-ms-tag-count:
- '2'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1242,15 +1297,15 @@ interactions:
ParameterSetName:
- -n -c --tier --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-access-tier:
- Hot
x-ms-date:
- - Mon, 18 Apr 2022 05:39:39 GMT
+ - Mon, 24 Oct 2022 06:06:20 GMT
x-ms-if-tags:
- category='test'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=tier
response:
@@ -1260,11 +1315,11 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:39 GMT
+ - Mon, 24 Oct 2022 06:06:24 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1284,13 +1339,13 @@ interactions:
ParameterSetName:
- -n -c --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:40 GMT
+ - Mon, 24 Oct 2022 06:06:24 GMT
x-ms-if-tags:
- category='test'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=snapshot
response:
@@ -1300,19 +1355,19 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:41 GMT
+ - Mon, 24 Oct 2022 06:06:28 GMT
etag:
- - '"0x8DA20FDC8AD7EFE"'
+ - '"0x8DAB585D45D6F0D"'
last-modified:
- - Mon, 18 Apr 2022 05:39:19 GMT
+ - Mon, 24 Oct 2022 06:06:02 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-server-encrypted:
- 'false'
x-ms-snapshot:
- - '2022-04-18T05:39:41.9265144Z'
+ - '2022-10-24T06:06:28.8519523Z'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 201
message: Created
@@ -1336,13 +1391,13 @@ interactions:
ParameterSetName:
- -n -c --tags-condition --tags --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:42 GMT
+ - Mon, 24 Oct 2022 06:06:28 GMT
x-ms-if-tags:
- category='test'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=tags
response:
@@ -1350,11 +1405,11 @@ interactions:
string: ''
headers:
date:
- - Mon, 18 Apr 2022 05:39:43 GMT
+ - Mon, 24 Oct 2022 06:06:30 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 204
message: No Content
@@ -1372,11 +1427,11 @@ interactions:
ParameterSetName:
- -n -c --tags-condition --tags --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:44 GMT
+ - Mon, 24 Oct 2022 06:06:30 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=tags
response:
@@ -1388,11 +1443,11 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:44 GMT
+ - Mon, 24 Oct 2022 06:06:30 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1410,13 +1465,13 @@ interactions:
ParameterSetName:
- -n -c --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:44 GMT
+ - Mon, 24 Oct 2022 06:06:30 GMT
x-ms-if-tags:
- category='test'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?comp=tags
response:
@@ -1428,11 +1483,11 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:46 GMT
+ - Mon, 24 Oct 2022 06:06:32 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1450,34 +1505,34 @@ interactions:
ParameterSetName:
- -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:47 GMT
+ - Mon, 24 Oct 2022 06:06:32 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003?restype=container&comp=list&maxresults=5000
response:
body:
string: "\uFEFF5000blob000005Mon,
- 18 Apr 2022 05:38:24 GMTMon, 18 Apr 2022 05:39:19
- GMT0x8DA20FDC8AD7EFE131072application/octet-streamMon, 24 Oct 2022 06:06:02
+ GMT0x8DAB585D45D6F0D131072application/octet-streamDfvoqkwgtS4bi/PLbL3xkw==BlockBlobHotMon,
- 18 Apr 2022 05:39:40 GMTunlockedavailabletrue2unlockedavailabletrue2"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:48 GMT
+ - Mon, 24 Oct 2022 06:06:34 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1495,40 +1550,40 @@ interactions:
ParameterSetName:
- -c --include --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:49 GMT
+ - Mon, 24 Oct 2022 06:06:34 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003?restype=container&comp=list&maxresults=5000&include=snapshots
response:
body:
string: "\uFEFF5000blob0000052022-04-18T05:39:41.9265144ZMon,
- 18 Apr 2022 05:38:24 GMTMon, 18 Apr 2022 05:39:19
- GMT0x8DA20FDC8AD7EFE131072application/octet-stream5000blob0000052022-10-24T06:06:28.8519523ZMon,
+ 24 Oct 2022 06:05:11 GMTMon, 24 Oct 2022 06:06:02
+ GMT0x8DAB585D45D6F0D131072application/octet-streamDfvoqkwgtS4bi/PLbL3xkw==BlockBlobHotMon,
- 18 Apr 2022 05:39:40 GMTtrue2blob000005Mon, 18 Apr
- 2022 05:38:24 GMTMon, 18 Apr 2022 05:39:19
- GMT0x8DA20FDC8AD7EFE131072application/octet-streamtrue2blob000005Mon, 24 Oct
+ 2022 06:05:11 GMTMon, 24 Oct 2022 06:06:02
+ GMT0x8DAB585D45D6F0D131072application/octet-streamDfvoqkwgtS4bi/PLbL3xkw==BlockBlobHotMon,
- 18 Apr 2022 05:39:40 GMTunlockedavailabletrue2unlockedavailabletrue2"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:50 GMT
+ - Mon, 24 Oct 2022 06:06:35 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -1548,15 +1603,15 @@ interactions:
ParameterSetName:
- -n -c --tags-condition --snapshot --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:51 GMT
+ - Mon, 24 Oct 2022 06:06:35 GMT
x-ms-if-tags:
- category='test'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: DELETE
- uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?snapshot=2022-04-18T05:39:41.9265144Z
+ uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005?snapshot=2022-10-24T06:06:28.8519523Z
response:
body:
string: ''
@@ -1564,13 +1619,13 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:52 GMT
+ - Mon, 24 Oct 2022 06:06:36 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-delete-type-permanent:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 202
message: Accepted
@@ -1590,13 +1645,13 @@ interactions:
ParameterSetName:
- -n -c --tags-condition --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:53 GMT
+ - Mon, 24 Oct 2022 06:06:37 GMT
x-ms-if-tags:
- category='test'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: DELETE
uri: https://blobtag000002.blob.core.windows.net/cont1000003/blob000005
response:
@@ -1606,13 +1661,13 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:39:54 GMT
+ - Mon, 24 Oct 2022 06:06:40 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-delete-type-permanent:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 202
message: Accepted
@@ -1630,11 +1685,11 @@ interactions:
ParameterSetName:
- -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:39:55 GMT
+ - Mon, 24 Oct 2022 06:06:40 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://blobtag000002.blob.core.windows.net/cont1000003?restype=container&comp=list&maxresults=5000
response:
@@ -1646,13 +1701,13 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:39:56 GMT
+ - Mon, 24 Oct 2022 06:06:42 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_versioning.yaml b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_versioning.yaml
index 7dd4b7998e0..dda0f58d464 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_versioning.yaml
+++ b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_versioning.yaml
@@ -13,9 +13,10 @@ interactions:
ParameterSetName:
- -n -g --enable-versioning
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: GET
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default?api-version=2022-05-01
response:
body:
string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false}}}'
@@ -27,7 +28,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:41:33 GMT
+ - Mon, 24 Oct 2022 07:21:23 GMT
expires:
- '-1'
pragma:
@@ -64,9 +65,10 @@ interactions:
ParameterSetName:
- -n -g --enable-versioning
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: PUT
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default?api-version=2022-05-01
response:
body:
string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false},"isVersioningEnabled":true}}'
@@ -78,7 +80,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:41:37 GMT
+ - Mon, 24 Oct 2022 07:21:25 GMT
expires:
- '-1'
pragma:
@@ -114,12 +116,13 @@ interactions:
ParameterSetName:
- -n -g --query -o
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: POST
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/listKeys?api-version=2021-09-01&$expand=kerb
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/listKeys?api-version=2022-05-01&$expand=kerb
response:
body:
- string: '{"keys":[{"creationTime":"2022-04-18T05:41:06.0840412Z","keyName":"key1","value":"veryFakedStorageAccountKey==","permissions":"FULL"},{"creationTime":"2022-04-18T05:41:06.0840412Z","keyName":"key2","value":"veryFakedStorageAccountKey==","permissions":"FULL"}]}'
+ string: '{"keys":[{"creationTime":"2022-10-24T07:21:00.7657965Z","keyName":"key1","value":"veryFakedStorageAccountKey==","permissions":"FULL"},{"creationTime":"2022-10-24T07:21:00.7657965Z","keyName":"key2","value":"veryFakedStorageAccountKey==","permissions":"FULL"}]}'
headers:
cache-control:
- no-cache
@@ -128,7 +131,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:41:42 GMT
+ - Mon, 24 Oct 2022 07:21:27 GMT
expires:
- '-1'
pragma:
@@ -150,136 +153,46 @@ interactions:
message: OK
- request:
body: null
- headers:
- Connection:
- - keep-alive
- Content-Length:
- - '0'
- User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
- x-ms-date:
- - Mon, 18 Apr 2022 05:41:43 GMT
- x-ms-version:
- - '2018-11-09'
- method: PUT
- uri: https://version000002.blob.core.windows.net/con000003?restype=container
- response:
- body:
- string: ''
- headers:
- content-length:
- - '0'
- date:
- - Mon, 18 Apr 2022 05:41:43 GMT
- etag:
- - '"0x8DA20FE1EDDFCB7"'
- last-modified:
- - Mon, 18 Apr 2022 05:41:43 GMT
- server:
- - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
- x-ms-version:
- - '2018-11-09'
- status:
- code: 201
- message: Created
-- request:
- body: "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
headers:
Accept:
- application/xml
Accept-Encoding:
- gzip, deflate
CommandName:
- - storage blob upload
+ - storage container create
Connection:
- keep-alive
Content-Length:
- - '1024'
- Content-Type:
- - application/octet-stream
- If-None-Match:
- - '*'
+ - '0'
ParameterSetName:
- - -c -f -n --account-name --account-key
+ - -n --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
- x-ms-blob-type:
- - BlockBlob
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:41:44 GMT
+ - Mon, 24 Oct 2022 07:21:27 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-06-08'
method: PUT
- uri: https://version000002.blob.core.windows.net/con000003/blob000004
+ uri: https://version000002.blob.core.windows.net/con000003?restype=container
response:
body:
string: ''
headers:
content-length:
- '0'
- content-md5:
- - DzQ7CTESaiDxM9Z8KwGKOw==
date:
- - Mon, 18 Apr 2022 05:41:44 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
etag:
- - '"0x8DA20FE1FCFF519"'
+ - '"0x8DAB5905ED2537E"'
last-modified:
- - Mon, 18 Apr 2022 05:41:45 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
- x-ms-content-crc64:
- - iknlm7CyG2k=
- x-ms-request-server-encrypted:
- - 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-06-08'
status:
code: 201
message: Created
-- request:
- body: null
- headers:
- Accept:
- - application/xml
- Accept-Encoding:
- - gzip, deflate
- CommandName:
- - storage blob list
- Connection:
- - keep-alive
- ParameterSetName:
- - -c --include --account-name --account-key
- User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
- x-ms-date:
- - Mon, 18 Apr 2022 05:41:46 GMT
- x-ms-version:
- - '2020-10-02'
- method: GET
- uri: https://version000002.blob.core.windows.net/con000003?restype=container&comp=list&maxresults=5000&include=versions
- response:
- body:
- string: "\uFEFF5000blob000004Mon,
- 18 Apr 2022 05:41:45 GMTMon, 18 Apr 2022 05:41:45
- GMT0x8DA20FE1FCFF5191024application/octet-streamDzQ7CTESaiDxM9Z8KwGKOw==BlockBlobHottrueunlockedavailabletrue"
- headers:
- content-type:
- - application/xml
- date:
- - Mon, 18 Apr 2022 05:41:46 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: "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
headers:
@@ -295,16 +208,18 @@ interactions:
- '1024'
Content-Type:
- application/octet-stream
+ If-None-Match:
+ - '*'
ParameterSetName:
- - -c -f -n --overwrite --account-name --account-key
+ - -c -f -n --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-blob-type:
- BlockBlob
x-ms-date:
- - Mon, 18 Apr 2022 05:41:57 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://version000002.blob.core.windows.net/con000003/blob000004
response:
@@ -316,11 +231,11 @@ interactions:
content-md5:
- DzQ7CTESaiDxM9Z8KwGKOw==
date:
- - Mon, 18 Apr 2022 05:41:58 GMT
+ - Mon, 24 Oct 2022 07:21:30 GMT
etag:
- - '"0x8DA20FE27D0328D"'
+ - '"0x8DAB5905FD53569"'
last-modified:
- - Mon, 18 Apr 2022 05:41:58 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-content-crc64:
@@ -328,9 +243,9 @@ interactions:
x-ms-request-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
x-ms-version-id:
- - '2022-04-18T05:41:58.8174312Z'
+ - '2022-10-24T07:21:31.4082931Z'
status:
code: 201
message: Created
@@ -348,24 +263,19 @@ interactions:
ParameterSetName:
- -c --include --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:41:59 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://version000002.blob.core.windows.net/con000003?restype=container&comp=list&maxresults=5000&include=versions
response:
body:
string: "\uFEFF5000blob0000042022-04-18T05:41:45.3850905ZMon,
- 18 Apr 2022 05:41:45 GMTMon, 18 Apr 2022 05:41:45
- GMT0x8DA20FE1FCFF5191024application/octet-streamDzQ7CTESaiDxM9Z8KwGKOw==BlockBlobHottruetrueblob0000042022-04-18T05:41:58.8174312ZtrueMon,
- 18 Apr 2022 05:41:58 GMTMon, 18 Apr 2022 05:41:58
- GMT0x8DA20FE27D0328D1024application/octet-stream5000blob0000042022-10-24T07:21:31.4082931ZtrueMon,
+ 24 Oct 2022 07:21:31 GMTMon, 24 Oct 2022 07:21:31
+ GMT0x8DAB5905FD535691024application/octet-streamDzQ7CTESaiDxM9Z8KwGKOw==BlockBlobHottrueunlockedavailabletrue"
@@ -373,13 +283,13 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:42:00 GMT
+ - Mon, 24 Oct 2022 07:21:32 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -401,13 +311,13 @@ interactions:
ParameterSetName:
- -c -f -n --overwrite --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-blob-type:
- BlockBlob
x-ms-date:
- - Mon, 18 Apr 2022 05:42:01 GMT
+ - Mon, 24 Oct 2022 07:21:32 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://version000002.blob.core.windows.net/con000003/blob000004
response:
@@ -419,11 +329,11 @@ interactions:
content-md5:
- yZp0xVU3GkM9Eh9VHWxjmA==
date:
- - Mon, 18 Apr 2022 05:42:01 GMT
+ - Mon, 24 Oct 2022 07:21:33 GMT
etag:
- - '"0x8DA20FE2A0EF92D"'
+ - '"0x8DAB59061A1EA2F"'
last-modified:
- - Mon, 18 Apr 2022 05:42:02 GMT
+ - Mon, 24 Oct 2022 07:21:34 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-content-crc64:
@@ -431,9 +341,9 @@ interactions:
x-ms-request-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
x-ms-version-id:
- - '2022-04-18T05:42:02.5762877Z'
+ - '2022-10-24T07:21:34.4275775Z'
status:
code: 201
message: Created
@@ -451,13 +361,13 @@ interactions:
ParameterSetName:
- -c -n --version-id --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:42:03 GMT
+ - Mon, 24 Oct 2022 07:21:34 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: HEAD
- uri: https://version000002.blob.core.windows.net/con000003/blob000004?versionid=2022-04-18T05%3A41%3A45.3850905Z
+ uri: https://version000002.blob.core.windows.net/con000003/blob000004?versionid=2022-10-24T07%3A21%3A31.4082931Z
response:
body:
string: ''
@@ -471,11 +381,11 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:42:03 GMT
+ - Mon, 24 Oct 2022 07:21:35 GMT
etag:
- - '"0x8DA20FE1FCFF519"'
+ - '"0x8DAB5905FD53569"'
last-modified:
- - Mon, 18 Apr 2022 05:41:45 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
@@ -485,13 +395,13 @@ interactions:
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:41:45 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
x-ms-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
x-ms-version-id:
- - '2022-04-18T05:41:45.3850905Z'
+ - '2022-10-24T07:21:31.4082931Z'
status:
code: 200
message: OK
@@ -509,15 +419,15 @@ interactions:
ParameterSetName:
- -c -n --version-id -f --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:42:05 GMT
+ - Mon, 24 Oct 2022 07:21:35 GMT
x-ms-range:
- bytes=0-33554431
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
- uri: https://version000002.blob.core.windows.net/con000003/blob000004?versionid=2022-04-18T05%3A41%3A45.3850905Z
+ uri: https://version000002.blob.core.windows.net/con000003/blob000004?versionid=2022-10-24T07%3A21%3A31.4082931Z
response:
body:
string: "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
@@ -531,11 +441,11 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:42:06 GMT
+ - Mon, 24 Oct 2022 07:21:37 GMT
etag:
- - '"0x8DA20FE1FCFF519"'
+ - '"0x8DAB5905FD53569"'
last-modified:
- - Mon, 18 Apr 2022 05:41:45 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-blob-content-md5:
@@ -543,13 +453,13 @@ interactions:
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:41:45 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
x-ms-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
x-ms-version-id:
- - '2022-04-18T05:41:45.3850905Z'
+ - '2022-10-24T07:21:31.4082931Z'
status:
code: 206
message: Partial Content
@@ -567,11 +477,11 @@ interactions:
ParameterSetName:
- -c -n --version-id -f --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:42:06 GMT
+ - Mon, 24 Oct 2022 07:21:36 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: HEAD
uri: https://version000002.blob.core.windows.net/con000003/blob000004
response:
@@ -587,11 +497,11 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:42:06 GMT
+ - Mon, 24 Oct 2022 07:21:37 GMT
etag:
- - '"0x8DA20FE2A0EF92D"'
+ - '"0x8DAB59061A1EA2F"'
last-modified:
- - Mon, 18 Apr 2022 05:42:02 GMT
+ - Mon, 24 Oct 2022 07:21:34 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
@@ -601,7 +511,7 @@ interactions:
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:42:02 GMT
+ - Mon, 24 Oct 2022 07:21:34 GMT
x-ms-is-current-version:
- 'true'
x-ms-lease-state:
@@ -611,9 +521,9 @@ interactions:
x-ms-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
x-ms-version-id:
- - '2022-04-18T05:42:02.5762877Z'
+ - '2022-10-24T07:21:34.4275775Z'
status:
code: 200
message: OK
@@ -633,15 +543,15 @@ interactions:
ParameterSetName:
- -c -n --version-id --tier --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-access-tier:
- Cool
x-ms-date:
- - Mon, 18 Apr 2022 05:42:07 GMT
+ - Mon, 24 Oct 2022 07:21:37 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
- uri: https://version000002.blob.core.windows.net/con000003/blob000004?comp=tier&versionid=2022-04-18T05%3A41%3A45.3850905Z
+ uri: https://version000002.blob.core.windows.net/con000003/blob000004?comp=tier&versionid=2022-10-24T07%3A21%3A31.4082931Z
response:
body:
string: ''
@@ -649,11 +559,11 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:42:07 GMT
+ - Mon, 24 Oct 2022 07:21:38 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -671,13 +581,13 @@ interactions:
ParameterSetName:
- -c -n --version-id --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:42:09 GMT
+ - Mon, 24 Oct 2022 07:21:40 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: HEAD
- uri: https://version000002.blob.core.windows.net/con000003/blob000004?versionid=2022-04-18T05%3A41%3A45.3850905Z
+ uri: https://version000002.blob.core.windows.net/con000003/blob000004?versionid=2022-10-24T07%3A21%3A31.4082931Z
response:
body:
string: ''
@@ -691,27 +601,27 @@ interactions:
content-type:
- application/octet-stream
date:
- - Mon, 18 Apr 2022 05:42:09 GMT
+ - Mon, 24 Oct 2022 07:21:41 GMT
etag:
- - '"0x8DA20FE1FCFF519"'
+ - '"0x8DAB5905FD53569"'
last-modified:
- - Mon, 18 Apr 2022 05:41:45 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-access-tier:
- Cool
x-ms-access-tier-change-time:
- - Mon, 18 Apr 2022 05:42:08 GMT
+ - Mon, 24 Oct 2022 07:21:39 GMT
x-ms-blob-type:
- BlockBlob
x-ms-creation-time:
- - Mon, 18 Apr 2022 05:41:45 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
x-ms-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
x-ms-version-id:
- - '2022-04-18T05:41:45.3850905Z'
+ - '2022-10-24T07:21:31.4082931Z'
status:
code: 200
message: OK
@@ -729,30 +639,25 @@ interactions:
ParameterSetName:
- -c --include --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:42:10 GMT
+ - Mon, 24 Oct 2022 07:21:41 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://version000002.blob.core.windows.net/con000003?restype=container&comp=list&maxresults=5000&include=versions
response:
body:
string: "\uFEFF5000blob0000042022-04-18T05:41:45.3850905ZMon,
- 18 Apr 2022 05:41:45 GMTMon, 18 Apr 2022 05:41:45
- GMT0x8DA20FE1FCFF5191024application/octet-stream5000blob0000042022-10-24T07:21:31.4082931ZMon,
+ 24 Oct 2022 07:21:31 GMTMon, 24 Oct 2022 07:21:31
+ GMT0x8DAB5905FD535691024application/octet-streamDzQ7CTESaiDxM9Z8KwGKOw==BlockBlobCoolMon,
- 18 Apr 2022 05:42:08 GMTtrueblob0000042022-04-18T05:41:58.8174312ZMon,
- 18 Apr 2022 05:41:58 GMTMon, 18 Apr 2022 05:41:58
- GMT0x8DA20FE27D0328D1024application/octet-streamDzQ7CTESaiDxM9Z8KwGKOw==BlockBlobHottruetrueblob0000042022-04-18T05:42:02.5762877ZtrueMon,
- 18 Apr 2022 05:42:02 GMTMon, 18 Apr 2022 05:42:02
- GMT0x8DA20FE2A0EF92D2048application/octet-streamtrueblob0000042022-10-24T07:21:34.4275775ZtrueMon,
+ 24 Oct 2022 07:21:34 GMTMon, 24 Oct 2022 07:21:34
+ GMT0x8DAB59061A1EA2F2048application/octet-streamyZp0xVU3GkM9Eh9VHWxjmA==BlockBlobHottrueunlockedavailabletrue"
@@ -760,13 +665,13 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:42:11 GMT
+ - Mon, 24 Oct 2022 07:21:42 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -786,13 +691,13 @@ interactions:
ParameterSetName:
- -c -n --version-id --account-name --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:42:13 GMT
+ - Mon, 24 Oct 2022 07:21:43 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: DELETE
- uri: https://version000002.blob.core.windows.net/con000003/blob000004?versionid=2022-04-18T05%3A41%3A45.3850905Z
+ uri: https://version000002.blob.core.windows.net/con000003/blob000004?versionid=2022-10-24T07%3A21%3A31.4082931Z
response:
body:
string: ''
@@ -800,13 +705,13 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:42:13 GMT
+ - Mon, 24 Oct 2022 07:21:44 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-delete-type-permanent:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 202
message: Accepted
@@ -824,24 +729,19 @@ interactions:
ParameterSetName:
- -c --include --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:42:15 GMT
+ - Mon, 24 Oct 2022 07:21:44 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://version000002.blob.core.windows.net/con000003?restype=container&comp=list&maxresults=5000&include=versions
response:
body:
string: "\uFEFF5000blob0000042022-04-18T05:41:58.8174312ZMon,
- 18 Apr 2022 05:41:58 GMTMon, 18 Apr 2022 05:41:58
- GMT0x8DA20FE27D0328D1024application/octet-streamDzQ7CTESaiDxM9Z8KwGKOw==BlockBlobHottruetrueblob0000042022-04-18T05:42:02.5762877ZtrueMon,
- 18 Apr 2022 05:42:02 GMTMon, 18 Apr 2022 05:42:02
- GMT0x8DA20FE2A0EF92D2048application/octet-stream5000blob0000042022-10-24T07:21:34.4275775ZtrueMon,
+ 24 Oct 2022 07:21:34 GMTMon, 24 Oct 2022 07:21:34
+ GMT0x8DAB59061A1EA2F2048application/octet-streamyZp0xVU3GkM9Eh9VHWxjmA==BlockBlobHottrueunlockedavailabletrue"
@@ -849,13 +749,13 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:42:15 GMT
+ - Mon, 24 Oct 2022 07:21:46 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_vlm.yaml b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_vlm.yaml
index 06fb83c2716..ca0e68913c6 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_vlm.yaml
+++ b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_blob_vlm.yaml
@@ -13,9 +13,10 @@ interactions:
ParameterSetName:
- -n -g --enable-versioning
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: GET
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default?api-version=2022-05-01
response:
body:
string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false}}}'
@@ -27,7 +28,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:43:03 GMT
+ - Mon, 24 Oct 2022 07:21:24 GMT
expires:
- '-1'
pragma:
@@ -64,9 +65,10 @@ interactions:
ParameterSetName:
- -n -g --enable-versioning
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: PUT
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default?api-version=2022-05-01
response:
body:
string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false},"isVersioningEnabled":true}}'
@@ -78,7 +80,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:43:06 GMT
+ - Mon, 24 Oct 2022 07:21:27 GMT
expires:
- '-1'
pragma:
@@ -94,7 +96,7 @@ interactions:
x-content-type-options:
- nosniff
x-ms-ratelimit-remaining-subscription-writes:
- - '1198'
+ - '1199'
status:
code: 200
message: OK
@@ -116,9 +118,10 @@ interactions:
ParameterSetName:
- -n --storage-account -g --enable-vlw
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: PUT
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default/containers/container000003?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default/containers/container000003?api-version=2022-05-01
response:
body:
string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/version000002/blobServices/default/containers/container000003","name":"container000003","type":"Microsoft.Storage/storageAccounts/blobServices/containers","properties":{"immutableStorageWithVersioning":{"enabled":true},"deleted":false,"remainingRetentionDays":0,"hasImmutabilityPolicy":false,"hasLegalHold":false}}'
@@ -130,9 +133,9 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:43:09 GMT
+ - Mon, 24 Oct 2022 07:21:28 GMT
etag:
- - '"0x8DA20FE51FDAAA7"'
+ - '"0x8DAB5905DE2FAF6"'
expires:
- '-1'
pragma:
@@ -144,7 +147,7 @@ interactions:
x-content-type-options:
- nosniff
x-ms-ratelimit-remaining-subscription-writes:
- - '1199'
+ - '1198'
status:
code: 201
message: Created
@@ -168,13 +171,13 @@ interactions:
ParameterSetName:
- -c -f -n --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-blob-type:
- BlockBlob
x-ms-date:
- - Mon, 18 Apr 2022 05:43:10 GMT
+ - Mon, 24 Oct 2022 07:21:28 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://version000002.blob.core.windows.net/container000003/blob000004
response:
@@ -186,11 +189,11 @@ interactions:
content-md5:
- EnZIEQLyGMmB4DJBgLr9nw==
date:
- - Mon, 18 Apr 2022 05:43:11 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
etag:
- - '"0x8DA20FE53359BAD"'
+ - '"0x8DAB5905EE430A9"'
last-modified:
- - Mon, 18 Apr 2022 05:43:11 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-content-crc64:
@@ -198,7 +201,7 @@ interactions:
x-ms-request-server-encrypted:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 201
message: Created
@@ -218,15 +221,15 @@ interactions:
ParameterSetName:
- -n -c --expiry-time --policy-mode --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:43:12 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
x-ms-immutability-policy-mode:
- Unlocked
x-ms-immutability-policy-until-date:
- - Mon, 18 Apr 2022 06:43:00 GMT
+ - Mon, 24 Oct 2022 08:21:00 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://version000002.blob.core.windows.net/container000003/blob000004?comp=immutabilityPolicies
response:
@@ -236,15 +239,15 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:43:12 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-immutability-policy-mode:
- unlocked
x-ms-immutability-policy-until-date:
- - Mon, 18 Apr 2022 06:43:00 GMT
+ - Mon, 24 Oct 2022 08:21:00 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -264,11 +267,11 @@ interactions:
ParameterSetName:
- -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:43:14 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: DELETE
uri: https://version000002.blob.core.windows.net/container000003/blob000004?comp=immutabilityPolicies
response:
@@ -278,11 +281,11 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:43:14 GMT
+ - Mon, 24 Oct 2022 07:21:34 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -302,13 +305,13 @@ interactions:
ParameterSetName:
- --legal-hold -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:43:16 GMT
+ - Mon, 24 Oct 2022 07:21:34 GMT
x-ms-legal-hold:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://version000002.blob.core.windows.net/container000003/blob000004?comp=legalhold
response:
@@ -318,13 +321,13 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:43:18 GMT
+ - Mon, 24 Oct 2022 07:21:37 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-legal-hold:
- 'true'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -344,13 +347,13 @@ interactions:
ParameterSetName:
- --legal-hold -n -c --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:43:20 GMT
+ - Mon, 24 Oct 2022 07:21:37 GMT
x-ms-legal-hold:
- 'false'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://version000002.blob.core.windows.net/container000003/blob000004?comp=legalhold
response:
@@ -360,13 +363,13 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:43:20 GMT
+ - Mon, 24 Oct 2022 07:21:39 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-legal-hold:
- 'false'
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_list_scenarios.yaml b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_list_scenarios.yaml
index 5768fda6b87..baa3de43b09 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_list_scenarios.yaml
+++ b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_list_scenarios.yaml
@@ -2,16 +2,24 @@ interactions:
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container create
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:20 GMT
+ - Mon, 24 Oct 2022 07:21:26 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: PUT
uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container
response:
@@ -21,31 +29,39 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:46:22 GMT
+ - Mon, 24 Oct 2022 07:21:27 GMT
etag:
- - '"0x8DA20FEC5B30669"'
+ - '"0x8DAB5905E1090B1"'
last-modified:
- - Mon, 18 Apr 2022 05:46:23 GMT
+ - Mon, 24 Oct 2022 07:21:28 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 201
message: Created
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container create
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:24 GMT
+ - Mon, 24 Oct 2022 07:21:28 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: PUT
uri: https://clitest000002.blob.core.windows.net/con2000004?restype=container
response:
@@ -55,15 +71,15 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:46:24 GMT
+ - Mon, 24 Oct 2022 07:21:28 GMT
etag:
- - '"0x8DA20FEC6BD9183"'
+ - '"0x8DAB5905EF303E3"'
last-modified:
- - Mon, 18 Apr 2022 05:46:25 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 201
message: Created
@@ -81,9 +97,10 @@ interactions:
ParameterSetName:
- -n -g --container-delete-retention-days --enable-container-delete-retention
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: GET
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2022-05-01
response:
body:
string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false}}}'
@@ -95,7 +112,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:46:27 GMT
+ - Mon, 24 Oct 2022 07:21:30 GMT
expires:
- '-1'
pragma:
@@ -133,12 +150,13 @@ interactions:
ParameterSetName:
- -n -g --container-delete-retention-days --enable-container-delete-retention
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: PUT
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2022-05-01
response:
body:
- string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false},"containerDeleteRetentionPolicy":{"enabled":true,"days":7}}}'
+ string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"containerDeleteRetentionPolicy":{"enabled":true,"days":7},"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false}}}'
headers:
cache-control:
- no-cache
@@ -147,7 +165,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:46:30 GMT
+ - Mon, 24 Oct 2022 07:21:33 GMT
expires:
- '-1'
pragma:
@@ -181,49 +199,57 @@ interactions:
ParameterSetName:
- --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:33 GMT
+ - Mon, 24 Oct 2022 07:21:33 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 05:46:23 GMT\"0x8DA20FEC5B30669\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsecon2000004Mon,
- 18 Apr 2022 05:46:25 GMT\"0x8DA20FEC6BD9183\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5905E1090B1\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsecon2000004Mon,
+ 24 Oct 2022 07:21:29 GMT\"0x8DAB5905EF303E3\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:46:33 GMT
+ - Mon, 24 Oct 2022 07:21:35 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container metadata update
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --metadata --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:34 GMT
+ - Mon, 24 Oct 2022 07:21:34 GMT
x-ms-meta-test:
- '1'
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: PUT
uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container&comp=metadata
response:
@@ -233,31 +259,39 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:46:34 GMT
+ - Mon, 24 Oct 2022 07:21:36 GMT
etag:
- - '"0x8DA20FECCDEC8AB"'
+ - '"0x8DAB5906303D1CB"'
last-modified:
- - Mon, 18 Apr 2022 05:46:35 GMT
+ - Mon, 24 Oct 2022 07:21:36 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 200
message: OK
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container metadata show
Connection:
- keep-alive
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:36 GMT
+ - Mon, 24 Oct 2022 07:21:36 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: GET
- uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container&comp=metadata
+ uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container
response:
body:
string: ''
@@ -265,17 +299,31 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:46:36 GMT
+ - Mon, 24 Oct 2022 07:21:37 GMT
etag:
- - '"0x8DA20FECCDEC8AB"'
+ - '"0x8DAB5906303D1CB"'
last-modified:
- - Mon, 18 Apr 2022 05:46:35 GMT
+ - Mon, 24 Oct 2022 07:21:36 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ 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-immutable-storage-with-versioning-enabled:
+ - 'false'
+ x-ms-lease-state:
+ - available
+ x-ms-lease-status:
+ - unlocked
x-ms-meta-test:
- '1'
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 200
message: OK
@@ -293,31 +341,31 @@ interactions:
ParameterSetName:
- --include-metadata --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:38 GMT
+ - Mon, 24 Oct 2022 07:21:38 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=metadata
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 05:46:35 GMT\"0x8DA20FECCDEC8AB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse1con2000004Mon,
- 18 Apr 2022 05:46:25 GMT\"0x8DA20FEC6BD9183\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5906303D1CB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse1con2000004Mon,
+ 24 Oct 2022 07:21:29 GMT\"0x8DAB5905EF303E3\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:46:38 GMT
+ - Mon, 24 Oct 2022 07:21:39 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -335,29 +383,29 @@ interactions:
ParameterSetName:
- --num-results --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:39 GMT
+ - Mon, 24 Oct 2022 07:21:40 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=1&include=
response:
body:
string: "\uFEFF1con1000003Mon,
- 18 Apr 2022 05:46:35 GMT\"0x8DA20FECCDEC8AB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse/clitest000002/con2000004"
+ 24 Oct 2022 07:21:36 GMT\"0x8DAB5906303D1CB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse/clitest000002/con2000004"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:46:40 GMT
+ - Mon, 24 Oct 2022 07:21:41 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -375,29 +423,29 @@ interactions:
ParameterSetName:
- --num-results --show-next-marker --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:41 GMT
+ - Mon, 24 Oct 2022 07:21:41 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=1&include=
response:
body:
string: "\uFEFF1con1000003Mon,
- 18 Apr 2022 05:46:35 GMT\"0x8DA20FECCDEC8AB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse/clitest000002/con2000004"
+ 24 Oct 2022 07:21:36 GMT\"0x8DAB5906303D1CB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse/clitest000002/con2000004"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:46:41 GMT
+ - Mon, 24 Oct 2022 07:21:43 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -415,30 +463,30 @@ interactions:
ParameterSetName:
- --marker --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:43 GMT
+ - Mon, 24 Oct 2022 07:21:43 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&marker=%2Fclitest000002%2Fcon2000004&maxresults=5000&include=
response:
body:
string: "\uFEFF/clitest000002/con20000045000con2000004Mon,
- 18 Apr 2022 05:46:25 GMT\"0x8DA20FEC6BD9183\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5905EF303E3\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:46:44 GMT
+ - Mon, 24 Oct 2022 07:21:45 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -456,46 +504,54 @@ interactions:
ParameterSetName:
- --prefix --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:46 GMT
+ - Mon, 24 Oct 2022 07:21:44 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&prefix=con1&maxresults=5000&include=
response:
body:
string: "\uFEFFcon15000con1000003Mon,
- 18 Apr 2022 05:46:35 GMT\"0x8DA20FECCDEC8AB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5906303D1CB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:46:46 GMT
+ - Mon, 24 Oct 2022 07:21:46 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container delete
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:47 GMT
+ - Mon, 24 Oct 2022 07:21:46 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: DELETE
uri: https://clitest000002.blob.core.windows.net/con2000004?restype=container
response:
@@ -505,11 +561,11 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:46:49 GMT
+ - Mon, 24 Oct 2022 07:21:47 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 202
message: Accepted
@@ -527,30 +583,30 @@ interactions:
ParameterSetName:
- --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:50 GMT
+ - Mon, 24 Oct 2022 07:21:48 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 05:46:35 GMT\"0x8DA20FECCDEC8AB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5906303D1CB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:46:50 GMT
+ - Mon, 24 Oct 2022 07:21:49 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -568,32 +624,32 @@ interactions:
ParameterSetName:
- --include-deleted --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:46:52 GMT
+ - Mon, 24 Oct 2022 07:21:49 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=deleted
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 05:46:35 GMT\"0x8DA20FECCDEC8AB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsecon2000004true01D852E7A44727B0Mon,
- 18 Apr 2022 05:46:25 GMT\"0x8DA20FEC6BD9183\"lockedleasedfixed$account-encryption-keyfalsefalsefalsefalseMon,
- 18 Apr 2022 05:46:49 GMT7\"0x8DAB5906303D1CB\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsecon2000004true01D8E7793C7C3581Mon,
+ 24 Oct 2022 07:21:29 GMT\"0x8DAB5905EF303E3\"lockedleasedfixed$account-encryption-keyfalsefalsefalsefalseMon,
+ 24 Oct 2022 07:21:48 GMT7"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:46:52 GMT
+ - Mon, 24 Oct 2022 07:21:50 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_soft_delete_oauth.yaml b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_soft_delete_oauth.yaml
index aa625bc566e..a9e6595f85c 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_soft_delete_oauth.yaml
+++ b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_soft_delete_oauth.yaml
@@ -15,12 +15,13 @@ interactions:
ParameterSetName:
- -n -g --query -o
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: POST
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/listKeys?api-version=2021-09-01&$expand=kerb
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/listKeys?api-version=2022-05-01&$expand=kerb
response:
body:
- string: '{"keys":[{"creationTime":"2022-04-18T07:11:32.4974824Z","keyName":"key1","value":"veryFakedStorageAccountKey==","permissions":"FULL"},{"creationTime":"2022-04-18T07:11:32.4974824Z","keyName":"key2","value":"veryFakedStorageAccountKey==","permissions":"FULL"}]}'
+ string: '{"keys":[{"creationTime":"2022-10-24T07:22:02.5962347Z","keyName":"key1","value":"veryFakedStorageAccountKey==","permissions":"FULL"},{"creationTime":"2022-10-24T07:22:02.5962347Z","keyName":"key2","value":"veryFakedStorageAccountKey==","permissions":"FULL"}]}'
headers:
cache-control:
- no-cache
@@ -29,7 +30,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 07:11:57 GMT
+ - Mon, 24 Oct 2022 07:22:27 GMT
expires:
- '-1'
pragma:
@@ -52,16 +53,24 @@ interactions:
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container create
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:11:58 GMT
+ - Mon, 24 Oct 2022 07:22:26 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: PUT
uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container
response:
@@ -71,15 +80,15 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 07:12:06 GMT
+ - Mon, 24 Oct 2022 07:22:28 GMT
etag:
- - '"0x8DA210ABF8C772B"'
+ - '"0x8DAB5908220FD16"'
last-modified:
- - Mon, 18 Apr 2022 07:12:07 GMT
+ - Mon, 24 Oct 2022 07:22:28 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 201
message: Created
@@ -97,9 +106,10 @@ interactions:
ParameterSetName:
- -n -g --container-delete-retention-days --enable-container-delete-retention
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: GET
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2022-05-01
response:
body:
string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false}}}'
@@ -111,7 +121,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 07:12:08 GMT
+ - Mon, 24 Oct 2022 07:22:30 GMT
expires:
- '-1'
pragma:
@@ -149,12 +159,13 @@ interactions:
ParameterSetName:
- -n -g --container-delete-retention-days --enable-container-delete-retention
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: PUT
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2022-05-01
response:
body:
- string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false},"containerDeleteRetentionPolicy":{"enabled":true,"days":7}}}'
+ string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"containerDeleteRetentionPolicy":{"enabled":true,"days":7},"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false}}}'
headers:
cache-control:
- no-cache
@@ -163,7 +174,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 07:12:10 GMT
+ - Mon, 24 Oct 2022 07:22:32 GMT
expires:
- '-1'
pragma:
@@ -179,7 +190,7 @@ interactions:
x-content-type-options:
- nosniff
x-ms-ratelimit-remaining-subscription-writes:
- - '1196'
+ - '1199'
status:
code: 200
message: OK
@@ -197,46 +208,54 @@ interactions:
ParameterSetName:
- --account-name --auth-mode
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:12:12 GMT
+ - Mon, 24 Oct 2022 07:22:32 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 07:12:07 GMT\"0x8DA210ABF8C772B\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5908220FD16\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 07:12:14 GMT
+ - Mon, 24 Oct 2022 07:22:36 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container delete
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --auth-mode
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:12:15 GMT
+ - Mon, 24 Oct 2022 07:22:36 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: DELETE
uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container
response:
@@ -246,11 +265,11 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 07:12:15 GMT
+ - Mon, 24 Oct 2022 07:22:37 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 202
message: Accepted
@@ -268,11 +287,11 @@ interactions:
ParameterSetName:
- --account-name --auth-mode
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:12:17 GMT
+ - Mon, 24 Oct 2022 07:22:38 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=
response:
@@ -284,13 +303,13 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 07:12:17 GMT
+ - Mon, 24 Oct 2022 07:22:39 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -308,31 +327,31 @@ interactions:
ParameterSetName:
- --include-deleted --account-name --auth-mode
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:12:18 GMT
+ - Mon, 24 Oct 2022 07:22:39 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=deleted
response:
body:
string: "\uFEFF5000con1000003true01D852F39D169066Mon,
- 18 Apr 2022 07:12:07 GMT\"0x8DA210ABF8C772B\"lockedleasedfixed$account-encryption-keyfalsefalsefalsefalseMon,
- 18 Apr 2022 07:12:16 GMT75000con1000003true01D8E7795FAA863AMon,
+ 24 Oct 2022 07:22:28 GMT\"0x8DAB5908220FD16\"lockedleasedfixed$account-encryption-keyfalsefalsefalsefalseMon,
+ 24 Oct 2022 07:22:38 GMT7"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 07:12:18 GMT
+ - Mon, 24 Oct 2022 07:22:40 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -350,31 +369,31 @@ interactions:
ParameterSetName:
- --include-deleted --query -o --account-name --auth-mode
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:12:50 GMT
+ - Mon, 24 Oct 2022 07:23:11 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=deleted
response:
body:
string: "\uFEFF5000con1000003true01D852F39D169066Mon,
- 18 Apr 2022 07:12:07 GMT\"0x8DA210ABF8C772B\"unlockedexpired$account-encryption-keyfalsefalsefalsefalseMon,
- 18 Apr 2022 07:12:16 GMT75000con1000003true01D8E7795FAA863AMon,
+ 24 Oct 2022 07:22:28 GMT\"0x8DAB5908220FD16\"unlockedexpired$account-encryption-keyfalsefalsefalsefalseMon,
+ 24 Oct 2022 07:22:38 GMT7"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 07:12:51 GMT
+ - Mon, 24 Oct 2022 07:23:12 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -394,15 +413,15 @@ interactions:
ParameterSetName:
- -n --deleted-version --account-name --auth-mode
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:12:52 GMT
+ - Mon, 24 Oct 2022 07:23:13 GMT
x-ms-deleted-container-name:
- - con1hxuybeeihdtjf7wblaqg
+ - con1pchkau3ecxkeerpai2gf
x-ms-deleted-container-version:
- - 01D852F39D169066
+ - 01D8E7795FAA863A
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container&comp=undelete
response:
@@ -412,11 +431,11 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 07:12:52 GMT
+ - Mon, 24 Oct 2022 07:23:15 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 201
message: Created
@@ -434,30 +453,30 @@ interactions:
ParameterSetName:
- --account-name --auth-mode
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:12:54 GMT
+ - Mon, 24 Oct 2022 07:23:14 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 07:12:53 GMT\"0x8DA210ADAE72629\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5909DBF9CA0\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 07:12:54 GMT
+ - Mon, 24 Oct 2022 07:23:16 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -475,30 +494,30 @@ interactions:
ParameterSetName:
- --include-deleted --account-name --auth-mode
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 07:12:55 GMT
+ - Mon, 24 Oct 2022 07:23:16 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=deleted
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 07:12:53 GMT\"0x8DA210ADAE72629\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5909DBF9CA0\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 07:12:56 GMT
+ - Mon, 24 Oct 2022 07:23:17 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_soft_delete_scenarios.yaml b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_soft_delete_scenarios.yaml
index c74b28bcd71..6abb12c4ead 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_soft_delete_scenarios.yaml
+++ b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/recordings/test_storage_container_soft_delete_scenarios.yaml
@@ -15,12 +15,13 @@ interactions:
ParameterSetName:
- -n -g --query -o
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: POST
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/listKeys?api-version=2021-09-01&$expand=kerb
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/listKeys?api-version=2022-05-01&$expand=kerb
response:
body:
- string: '{"keys":[{"creationTime":"2022-04-18T05:47:12.0713255Z","keyName":"key1","value":"veryFakedStorageAccountKey==","permissions":"FULL"},{"creationTime":"2022-04-18T05:47:12.0713255Z","keyName":"key2","value":"veryFakedStorageAccountKey==","permissions":"FULL"}]}'
+ string: '{"keys":[{"creationTime":"2022-10-24T07:20:59.8126352Z","keyName":"key1","value":"veryFakedStorageAccountKey==","permissions":"FULL"},{"creationTime":"2022-10-24T07:20:59.8126352Z","keyName":"key2","value":"veryFakedStorageAccountKey==","permissions":"FULL"}]}'
headers:
cache-control:
- no-cache
@@ -29,7 +30,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:47:35 GMT
+ - Mon, 24 Oct 2022 07:21:24 GMT
expires:
- '-1'
pragma:
@@ -52,16 +53,24 @@ interactions:
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container create
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:47:36 GMT
+ - Mon, 24 Oct 2022 07:21:24 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: PUT
uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container
response:
@@ -71,15 +80,15 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:47:36 GMT
+ - Mon, 24 Oct 2022 07:21:25 GMT
etag:
- - '"0x8DA20FEF1C5EAD8"'
+ - '"0x8DAB5905D1C7001"'
last-modified:
- - Mon, 18 Apr 2022 05:47:37 GMT
+ - Mon, 24 Oct 2022 07:21:26 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 201
message: Created
@@ -97,9 +106,10 @@ interactions:
ParameterSetName:
- -n -g --container-delete-retention-days --enable-container-delete-retention
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: GET
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2022-05-01
response:
body:
string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false}}}'
@@ -111,7 +121,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:47:38 GMT
+ - Mon, 24 Oct 2022 07:21:28 GMT
expires:
- '-1'
pragma:
@@ -149,12 +159,13 @@ interactions:
ParameterSetName:
- -n -g --container-delete-retention-days --enable-container-delete-retention
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-azure-mgmt-storage/20.0.0 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-azure-mgmt-storage/20.1.0 Python/3.7.9
+ (Windows-10-10.0.22621-SP0)
method: PUT
- uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2021-09-01
+ uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default?api-version=2022-05-01
response:
body:
- string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false},"containerDeleteRetentionPolicy":{"enabled":true,"days":7}}}'
+ string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest000001/providers/Microsoft.Storage/storageAccounts/clitest000002/blobServices/default","name":"default","type":"Microsoft.Storage/storageAccounts/blobServices","properties":{"containerDeleteRetentionPolicy":{"enabled":true,"days":7},"cors":{"corsRules":[]},"deleteRetentionPolicy":{"allowPermanentDelete":false,"enabled":false}}}'
headers:
cache-control:
- no-cache
@@ -163,7 +174,7 @@ interactions:
content-type:
- application/json
date:
- - Mon, 18 Apr 2022 05:47:41 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
expires:
- '-1'
pragma:
@@ -179,7 +190,7 @@ interactions:
x-content-type-options:
- nosniff
x-ms-ratelimit-remaining-subscription-writes:
- - '1198'
+ - '1199'
status:
code: 200
message: OK
@@ -197,46 +208,54 @@ interactions:
ParameterSetName:
- --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:47:43 GMT
+ - Mon, 24 Oct 2022 07:21:29 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 05:47:37 GMT\"0x8DA20FEF1C5EAD8\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB5905D1C7001\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:47:43 GMT
+ - Mon, 24 Oct 2022 07:21:30 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
- request:
body: null
headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ CommandName:
+ - storage container delete
Connection:
- keep-alive
Content-Length:
- '0'
+ ParameterSetName:
+ - -n --account-name --account-key
User-Agent:
- - Azure-Storage/2.0.0-2.0.1 (Python CPython 3.8.7; Windows 10) AZURECLI/2.35.0
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.12.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:47:44 GMT
+ - Mon, 24 Oct 2022 07:21:31 GMT
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
method: DELETE
uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container
response:
@@ -246,11 +265,11 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:47:44 GMT
+ - Mon, 24 Oct 2022 07:21:32 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2018-11-09'
+ - '2021-06-08'
status:
code: 202
message: Accepted
@@ -268,11 +287,11 @@ interactions:
ParameterSetName:
- --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:47:46 GMT
+ - Mon, 24 Oct 2022 07:21:32 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=
response:
@@ -284,13 +303,13 @@ interactions:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:47:46 GMT
+ - Mon, 24 Oct 2022 07:21:33 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -308,31 +327,31 @@ interactions:
ParameterSetName:
- --include-deleted --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:47:48 GMT
+ - Mon, 24 Oct 2022 07:21:34 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=deleted
response:
body:
string: "\uFEFF5000con1000003true01D852E7CF4EF55EMon,
- 18 Apr 2022 05:47:37 GMT\"0x8DA20FEF1C5EAD8\"lockedleasedfixed$account-encryption-keyfalsefalsefalsefalseMon,
- 18 Apr 2022 05:47:45 GMT75000con1000003true01D8E7793AA55F61Mon,
+ 24 Oct 2022 07:21:26 GMT\"0x8DAB5905D1C7001\"lockedleasedfixed$account-encryption-keyfalsefalsefalsefalseMon,
+ 24 Oct 2022 07:21:33 GMT7"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:47:48 GMT
+ - Mon, 24 Oct 2022 07:21:36 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -350,31 +369,31 @@ interactions:
ParameterSetName:
- --include-deleted --query -o --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:48:19 GMT
+ - Mon, 24 Oct 2022 07:22:05 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=deleted
response:
body:
string: "\uFEFF5000con1000003true01D852E7CF4EF55EMon,
- 18 Apr 2022 05:47:37 GMT\"0x8DA20FEF1C5EAD8\"unlockedexpired$account-encryption-keyfalsefalsefalsefalseMon,
- 18 Apr 2022 05:47:45 GMT75000con1000003true01D8E7793AA55F61Mon,
+ 24 Oct 2022 07:21:26 GMT\"0x8DAB5905D1C7001\"unlockedexpired$account-encryption-keyfalsefalsefalsefalseMon,
+ 24 Oct 2022 07:21:33 GMT7"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:48:19 GMT
+ - Mon, 24 Oct 2022 07:22:07 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -394,15 +413,15 @@ interactions:
ParameterSetName:
- -n --deleted-version --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:48:21 GMT
+ - Mon, 24 Oct 2022 07:22:07 GMT
x-ms-deleted-container-name:
- - con1lo4ptk7kri2rw2odiw4u
+ - con1w7ehfgrhmcwol5n7kit4
x-ms-deleted-container-version:
- - 01D852E7CF4EF55E
+ - 01D8E7793AA55F61
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: PUT
uri: https://clitest000002.blob.core.windows.net/con1000003?restype=container&comp=undelete
response:
@@ -412,11 +431,11 @@ interactions:
content-length:
- '0'
date:
- - Mon, 18 Apr 2022 05:48:22 GMT
+ - Mon, 24 Oct 2022 07:22:10 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 201
message: Created
@@ -434,30 +453,30 @@ interactions:
ParameterSetName:
- --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:48:24 GMT
+ - Mon, 24 Oct 2022 07:22:10 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 05:48:23 GMT\"0x8DA20FF0D13448F\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB590776AFF34\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:48:24 GMT
+ - Mon, 24 Oct 2022 07:22:12 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
@@ -475,30 +494,30 @@ interactions:
ParameterSetName:
- --include-deleted --account-name --account-key
User-Agent:
- - AZURECLI/2.35.0 azsdk-python-storage-blob/12.9.0b1 Python/3.8.7 (Windows-10-10.0.22000-SP0)
+ - AZURECLI/2.41.0 (PIP) azsdk-python-storage-blob/12.11.0 Python/3.7.9 (Windows-10-10.0.22621-SP0)
x-ms-date:
- - Mon, 18 Apr 2022 05:48:26 GMT
+ - Mon, 24 Oct 2022 07:22:12 GMT
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
method: GET
uri: https://clitest000002.blob.core.windows.net/?comp=list&maxresults=5000&include=deleted
response:
body:
string: "\uFEFF5000con1000003Mon,
- 18 Apr 2022 05:48:23 GMT\"0x8DA20FF0D13448F\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse\"0x8DAB590776AFF34\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse"
headers:
content-type:
- application/xml
date:
- - Mon, 18 Apr 2022 05:48:27 GMT
+ - Mon, 24 Oct 2022 07:22:14 GMT
server:
- Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
transfer-encoding:
- chunked
x-ms-version:
- - '2020-10-02'
+ - '2021-04-10'
status:
code: 200
message: OK
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/test_storage_blob_preview_scenario.py b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/test_storage_blob_preview_scenario.py
index d21c4427596..9ef5ac10516 100644
--- a/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/test_storage_blob_preview_scenario.py
+++ b/src/storage-blob-preview/azext_storage_blob_preview/tests/latest/test_storage_blob_preview_scenario.py
@@ -240,6 +240,12 @@ def test_storage_blob_tags_scenario(self, resource_group, storage_account_info):
JMESPathCheck('[0].containerName', container1),
JMESPathCheck('[0].name', blob_name1))
+ # find blobs in specified container with index tags
+ self.storage_cmd("storage blob filter --tag-filter \"test='tag'\" -c {}", account_info, container1). \
+ assert_with_checks(JMESPathCheck('length(@)', 1),
+ JMESPathCheck('[0].containerName', container1),
+ JMESPathCheck('[0].name', blob_name1))
+
# tag condition
tag_condition = "test=\'tag\'"
self.storage_cmd('storage blob copy start --source-blob {} --source-container {} -c {} -b {} '
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/__init__.py
new file mode 100644
index 00000000000..58442edc91e
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/__init__.py
@@ -0,0 +1,239 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+import os
+
+from typing import Union, Iterable, AnyStr, IO, Any, Dict # pylint: disable=unused-import
+from ._version import VERSION
+from ._blob_client import BlobClient
+from ._container_client import ContainerClient
+from ._blob_service_client import BlobServiceClient
+from ._lease import BlobLeaseClient
+from ._download import StorageStreamDownloader
+from ._quick_query_helper import BlobQueryReader
+from ._shared_access_signature import generate_account_sas, generate_container_sas, generate_blob_sas
+from ._shared.policies import ExponentialRetry, LinearRetry
+from ._shared.response_handlers import PartialBatchErrorException
+from ._shared.models import(
+ LocationMode,
+ ResourceTypes,
+ AccountSasPermissions,
+ StorageErrorCode,
+ UserDelegationKey
+)
+from ._generated.models import (
+ RehydratePriority,
+)
+from ._models import (
+ BlobType,
+ BlockState,
+ StandardBlobTier,
+ PremiumPageBlobTier,
+ BlobImmutabilityPolicyMode,
+ SequenceNumberAction,
+ PublicAccess,
+ BlobAnalyticsLogging,
+ Metrics,
+ RetentionPolicy,
+ StaticWebsite,
+ CorsRule,
+ ContainerProperties,
+ BlobProperties,
+ FilteredBlob,
+ LeaseProperties,
+ ContentSettings,
+ CopyProperties,
+ BlobBlock,
+ PageRange,
+ AccessPolicy,
+ ContainerSasPermissions,
+ BlobSasPermissions,
+ CustomerProvidedEncryptionKey,
+ ContainerEncryptionScope,
+ BlobQueryError,
+ DelimitedJsonDialect,
+ DelimitedTextDialect,
+ QuickQueryDialect,
+ ArrowDialect,
+ ArrowType,
+ ObjectReplicationPolicy,
+ ObjectReplicationRule,
+ ImmutabilityPolicy
+)
+from ._list_blobs_helper import BlobPrefix
+
+__version__ = VERSION
+
+
+def upload_blob_to_url(
+ blob_url, # type: str
+ data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
+ credential=None, # type: Any
+ **kwargs):
+ # type: (...) -> Dict[str, Any]
+ """Upload data to a given URL
+
+ The data will be uploaded as a block blob.
+
+ :param str blob_url:
+ The full URI to the blob. This can also include a SAS token.
+ :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:
+ 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.
+ 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.
+ :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
+ operation will fail with a ResourceExistsError.
+ :keyword int max_concurrency:
+ The number of parallel connections with which to download.
+ :keyword int length:
+ Number of bytes to read from the stream. This is optional, but
+ should be supplied for optimal performance.
+ :keyword dict(str,str) metadata:
+ Name-value pairs associated with the blob as metadata.
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash for each chunk of the blob. The storage
+ service checks the hash of the content that has arrived with the hash
+ that was sent. This is primarily valuable for detecting bitflips on
+ the wire if using http instead of https as https (the default) will
+ already validate. Note that this MD5 hash is not stored with the
+ blob. Also note that if enabled, the memory-efficient upload algorithm
+ will not be used, because computing the MD5 hash requires buffering
+ entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
+ :keyword str encoding:
+ Encoding to use if text is supplied as input. Defaults to UTF-8.
+ :returns: Blob-updated property dict (Etag and last modified)
+ :rtype: dict(str, Any)
+ """
+ with BlobClient.from_blob_url(blob_url, credential=credential) as client:
+ return client.upload_blob(data=data, blob_type=BlobType.BlockBlob, **kwargs)
+
+
+def _download_to_stream(client, handle, **kwargs):
+ """Download data to specified open file-handle."""
+ stream = client.download_blob(**kwargs)
+ stream.readinto(handle)
+
+
+def download_blob_from_url(
+ blob_url, # type: str
+ output, # type: str
+ credential=None, # type: Any
+ **kwargs):
+ # type: (...) -> None
+ """Download the contents of a blob to a local file or stream.
+
+ :param str blob_url:
+ The full URI to the blob. This can also include a SAS token.
+ :param output:
+ Where the data should be downloaded to. This could be either a file path to write to,
+ or an open IO handle to write to.
+ :type output: str or writable stream.
+ :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 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.
+ :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
+ `True`, an attempt will be made to write to the existing file. If a stream handle is passed
+ in, this value is ignored.
+ :keyword int max_concurrency:
+ The number of parallel connections with which to download.
+ :keyword int offset:
+ Start of byte range to use for downloading a section of the blob.
+ Must be set if length is provided.
+ :keyword int length:
+ Number of bytes to read from the stream. This is optional, but
+ should be supplied for optimal performance.
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash for each chunk of the blob. The storage
+ service checks the hash of the content that has arrived with the hash
+ that was sent. This is primarily valuable for detecting bitflips on
+ the wire if using http instead of https as https (the default) will
+ already validate. Note that this MD5 hash is not stored with the
+ blob. Also note that if enabled, the memory-efficient upload algorithm
+ will not be used, because computing the MD5 hash requires buffering
+ entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
+ :rtype: None
+ """
+ overwrite = kwargs.pop('overwrite', False)
+ with BlobClient.from_blob_url(blob_url, credential=credential) as client:
+ if hasattr(output, 'write'):
+ _download_to_stream(client, output, **kwargs)
+ else:
+ if not overwrite and os.path.isfile(output):
+ raise ValueError("The file '{}' already exists.".format(output))
+ with open(output, 'wb') as file_handle:
+ _download_to_stream(client, file_handle, **kwargs)
+
+
+__all__ = [
+ 'upload_blob_to_url',
+ 'download_blob_from_url',
+ 'BlobServiceClient',
+ 'ContainerClient',
+ 'BlobClient',
+ 'BlobType',
+ 'BlobLeaseClient',
+ 'StorageErrorCode',
+ 'UserDelegationKey',
+ 'ExponentialRetry',
+ 'LinearRetry',
+ 'LocationMode',
+ 'BlockState',
+ 'StandardBlobTier',
+ 'PremiumPageBlobTier',
+ 'SequenceNumberAction',
+ 'BlobImmutabilityPolicyMode',
+ 'ImmutabilityPolicy',
+ 'PublicAccess',
+ 'BlobAnalyticsLogging',
+ 'Metrics',
+ 'RetentionPolicy',
+ 'StaticWebsite',
+ 'CorsRule',
+ 'ContainerProperties',
+ 'BlobProperties',
+ 'BlobPrefix',
+ 'FilteredBlob',
+ 'LeaseProperties',
+ 'ContentSettings',
+ 'CopyProperties',
+ 'BlobBlock',
+ 'PageRange',
+ 'AccessPolicy',
+ 'QuickQueryDialect',
+ 'ContainerSasPermissions',
+ 'BlobSasPermissions',
+ 'ResourceTypes',
+ 'AccountSasPermissions',
+ 'StorageStreamDownloader',
+ 'CustomerProvidedEncryptionKey',
+ 'RehydratePriority',
+ 'generate_account_sas',
+ 'generate_container_sas',
+ 'generate_blob_sas',
+ 'PartialBatchErrorException',
+ 'ContainerEncryptionScope',
+ 'BlobQueryError',
+ 'DelimitedJsonDialect',
+ 'DelimitedTextDialect',
+ 'ArrowDialect',
+ 'ArrowType',
+ 'BlobQueryReader',
+ 'ObjectReplicationPolicy',
+ 'ObjectReplicationRule'
+]
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_blob_client.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_blob_client.py
new file mode 100644
index 00000000000..65f901fe9be
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_blob_client.py
@@ -0,0 +1,4003 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=too-many-lines,no-self-use
+from functools import partial
+from io import BytesIO
+from typing import ( # pylint: disable=unused-import
+ Union, Optional, Any, IO, Iterable, AnyStr, Dict, List, Tuple,
+ TYPE_CHECKING,
+ TypeVar, Type)
+
+try:
+ from urllib.parse import urlparse, quote, unquote
+except ImportError:
+ from urlparse import urlparse # type: ignore
+ from urllib2 import quote, unquote # type: ignore
+import six
+from azure.core.pipeline import Pipeline
+from azure.core.tracing.decorator import distributed_trace
+from azure.core.exceptions import ResourceNotFoundError, HttpResponseError, ResourceExistsError
+
+from ._shared import encode_base64
+from ._shared.base_client import StorageAccountHostsMixin, parse_connection_str, parse_query, TransportWrapper
+from ._shared.encryption import generate_blob_encryption_data
+from ._shared.uploads import IterStreamer
+from ._shared.request_handlers import (
+ add_metadata_headers, get_length, read_length,
+ validate_and_format_range_headers)
+from ._shared.response_handlers import return_response_headers, process_storage_error, return_headers_and_deserialized
+from ._generated import AzureBlobStorage
+from ._generated.models import ( # pylint: disable=unused-import
+ DeleteSnapshotsOptionType,
+ BlobHTTPHeaders,
+ BlockLookupList,
+ AppendPositionAccessConditions,
+ SequenceNumberAccessConditions,
+ QueryRequest,
+ CpkInfo)
+from ._serialize import (
+ get_modify_conditions,
+ get_source_conditions,
+ get_cpk_scope_info,
+ get_api_version,
+ serialize_blob_tags_header,
+ serialize_blob_tags,
+ serialize_query_format, get_access_conditions
+)
+from ._deserialize import get_page_ranges_result, deserialize_blob_properties, deserialize_blob_stream, parse_tags, \
+ deserialize_pipeline_response_into_cls
+from ._quick_query_helper import BlobQueryReader
+from ._upload_helpers import (
+ upload_block_blob,
+ upload_append_blob,
+ upload_page_blob, _any_conditions)
+from ._models import BlobType, BlobBlock, BlobProperties, BlobQueryError, QuickQueryDialect, \
+ DelimitedJsonDialect, DelimitedTextDialect
+from ._download import StorageStreamDownloader
+from ._lease import BlobLeaseClient
+
+if TYPE_CHECKING:
+ from datetime import datetime
+ from ._generated.models import BlockList
+ from ._models import ( # pylint: disable=unused-import
+ ContentSettings,
+ ImmutabilityPolicy,
+ PremiumPageBlobTier,
+ StandardBlobTier,
+ SequenceNumberAction
+ )
+
+_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION = (
+ 'The require_encryption flag is set, but encryption is not supported'
+ ' for this method.')
+
+ClassType = TypeVar("ClassType")
+
+
+class BlobClient(StorageAccountHostsMixin): # pylint: disable=too-many-public-methods
+ """A client to interact with a specific blob, although that blob may not yet exist.
+
+ For more optional configuration, please click
+ `here `_.
+
+ :param str account_url:
+ The URI to the storage account. In order to create a client given the full URI to the blob,
+ use the :func:`from_blob_url` classmethod.
+ :param container_name: The container name for the blob.
+ :type container_name: str
+ :param blob_name: The name of the blob with which to interact. If specified, this value will override
+ a blob value specified in the blob URL.
+ :type blob_name: str
+ :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`.
+ :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.
+ 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.
+ :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.
+
+ .. versionadded:: 12.2.0
+
+ :keyword str secondary_hostname:
+ The hostname of the secondary endpoint.
+ :keyword int max_block_size: The maximum chunk size for uploading a block blob in chunks.
+ Defaults to 4*1024*1024, or 4MB.
+ :keyword int max_single_put_size: If the blob size is less than or equal max_single_put_size, then the blob will be
+ uploaded with only one http PUT request. If the blob size is larger than max_single_put_size,
+ the blob will be uploaded in chunks. Defaults to 64*1024*1024, or 64MB.
+ :keyword int min_large_block_upload_threshold: The minimum chunk size required to use the memory efficient
+ algorithm when uploading a block blob. Defaults to 4*1024*1024+1.
+ :keyword bool use_byte_buffer: Use a byte buffer for block blob uploads. Defaults to False.
+ :keyword int max_page_size: The maximum chunk size for uploading a page blob. Defaults to 4*1024*1024, or 4MB.
+ :keyword int max_single_get_size: The maximum size for a blob to be downloaded in a single call,
+ the exceeded part will be downloaded in chunks (could be parallel). Defaults to 32*1024*1024, or 32MB.
+ :keyword int max_chunk_get_size: The maximum chunk size used for downloading a blob. Defaults to 4*1024*1024,
+ or 4MB.
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_authentication.py
+ :start-after: [START create_blob_client]
+ :end-before: [END create_blob_client]
+ :language: python
+ :dedent: 8
+ :caption: Creating the BlobClient from a URL to a public blob (no auth needed).
+
+ .. literalinclude:: ../samples/blob_samples_authentication.py
+ :start-after: [START create_blob_client_sas_url]
+ :end-before: [END create_blob_client_sas_url]
+ :language: python
+ :dedent: 8
+ :caption: Creating the BlobClient from a SAS URL to a blob.
+ """
+ def __init__(
+ self, account_url, # type: str
+ container_name, # type: str
+ blob_name, # type: str
+ snapshot=None, # type: Optional[Union[str, Dict[str, Any]]]
+ credential=None, # type: Optional[Any]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ try:
+ if not account_url.lower().startswith('http'):
+ account_url = "https://" + account_url
+ except AttributeError:
+ raise ValueError("Account URL must be a string.")
+ parsed_url = urlparse(account_url.rstrip('/'))
+
+ if not (container_name and blob_name):
+ raise ValueError("Please specify a container name and blob name.")
+ if not parsed_url.netloc:
+ raise ValueError("Invalid URL: {}".format(account_url))
+
+ path_snapshot, sas_token = parse_query(parsed_url.query)
+
+ self.container_name = container_name
+ self.blob_name = blob_name
+ try:
+ self.snapshot = snapshot.snapshot # type: ignore
+ except AttributeError:
+ try:
+ self.snapshot = snapshot['snapshot'] # type: ignore
+ except TypeError:
+ self.snapshot = snapshot or path_snapshot
+
+ # This parameter is used for the hierarchy traversal. Give precedence to credential.
+ self._raw_credential = credential if credential else sas_token
+ self._query_str, credential = self._format_query_string(sas_token, credential, snapshot=self.snapshot)
+ super(BlobClient, self).__init__(parsed_url, service='blob', credential=credential, **kwargs)
+ self._client = AzureBlobStorage(self.url, pipeline=self._pipeline)
+ self._client._config.version = get_api_version(kwargs) # pylint: disable=protected-access
+
+ def _format_url(self, hostname):
+ container_name = self.container_name
+ if isinstance(container_name, six.text_type):
+ container_name = container_name.encode('UTF-8')
+ return "{}://{}/{}/{}{}".format(
+ self.scheme,
+ hostname,
+ quote(container_name),
+ quote(self.blob_name, safe='~/'),
+ self._query_str)
+
+ def _encode_source_url(self, source_url):
+ parsed_source_url = urlparse(source_url)
+ source_scheme = parsed_source_url.scheme
+ source_hostname = parsed_source_url.netloc.rstrip('/')
+ source_path = unquote(parsed_source_url.path)
+ source_query = parsed_source_url.query
+ result = ["{}://{}{}".format(source_scheme, source_hostname, quote(source_path, safe='~/'))]
+ if source_query:
+ result.append(source_query)
+ 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
+ """Create BlobClient from a blob url. This doesn't support customized blob url with '/' in blob name.
+
+ :param str blob_url:
+ The full endpoint URL to the Blob, including SAS token and snapshot if used. This could be
+ either the primary endpoint, or the secondary endpoint depending on the current `location_mode`.
+ :type blob_url: str
+ :param credential:
+ 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.
+ 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.
+ :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
+ the snapshot in the url.
+ :returns: A Blob client.
+ :rtype: ~azure.storage.blob.BlobClient
+ """
+ try:
+ if not blob_url.lower().startswith('http'):
+ blob_url = "https://" + blob_url
+ except AttributeError:
+ raise ValueError("Blob URL must be a string.")
+ parsed_url = urlparse(blob_url.rstrip('/'))
+
+ if not parsed_url.netloc:
+ raise ValueError("Invalid URL: {}".format(blob_url))
+
+ account_path = ""
+ if ".core." in parsed_url.netloc:
+ # .core. is indicating non-customized url. Blob name with directory info can also be parsed.
+ path_blob = parsed_url.path.lstrip('/').split('/', 1)
+ elif "localhost" in parsed_url.netloc or "127.0.0.1" in parsed_url.netloc:
+ path_blob = parsed_url.path.lstrip('/').split('/', 2)
+ account_path += '/' + path_blob[0]
+ else:
+ # for customized url. blob name that has directory info cannot be parsed.
+ path_blob = parsed_url.path.lstrip('/').split('/')
+ if len(path_blob) > 2:
+ account_path = "/" + "/".join(path_blob[:-2])
+ account_url = "{}://{}{}?{}".format(
+ parsed_url.scheme,
+ parsed_url.netloc.rstrip('/'),
+ account_path,
+ parsed_url.query)
+ container_name, blob_name = unquote(path_blob[-2]), unquote(path_blob[-1])
+ if not container_name or not blob_name:
+ raise ValueError("Invalid URL. Provide a blob_url with a valid blob and container name.")
+
+ path_snapshot, _ = parse_query(parsed_url.query)
+ if snapshot:
+ try:
+ path_snapshot = snapshot.snapshot # type: ignore
+ except AttributeError:
+ try:
+ path_snapshot = snapshot['snapshot'] # type: ignore
+ except TypeError:
+ path_snapshot = snapshot
+
+ return cls(
+ account_url, container_name=container_name, blob_name=blob_name,
+ snapshot=path_snapshot, credential=credential, **kwargs
+ )
+
+ @classmethod
+ def from_connection_string(
+ cls, # type: Type[ClassType]
+ conn_str, # type: str
+ container_name, # type: str
+ blob_name, # type: str
+ snapshot=None, # type: Optional[str]
+ credential=None, # type: Optional[Any]
+ **kwargs # type: Any
+ ): # type: (...) -> ClassType
+ """Create BlobClient from a Connection String.
+
+ :param str conn_str:
+ A connection string to an Azure Storage account.
+ :param container_name: The container name for the blob.
+ :type container_name: str
+ :param blob_name: The name of the blob with which to interact.
+ :type blob_name: str
+ :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`.
+ :param credential:
+ 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.
+ Credentials provided here will take precedence over those in the connection string.
+ :returns: A Blob client.
+ :rtype: ~azure.storage.blob.BlobClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_authentication.py
+ :start-after: [START auth_from_connection_string_blob]
+ :end-before: [END auth_from_connection_string_blob]
+ :language: python
+ :dedent: 8
+ :caption: Creating the BlobClient from a connection string.
+ """
+ account_url, secondary, credential = parse_connection_str(conn_str, credential, 'blob')
+ if 'secondary_hostname' not in kwargs:
+ kwargs['secondary_hostname'] = secondary
+ return cls(
+ account_url, container_name=container_name, blob_name=blob_name,
+ snapshot=snapshot, credential=credential, **kwargs
+ )
+
+ @distributed_trace
+ def get_account_information(self, **kwargs):
+ # type: (**Any) -> Dict[str, str]
+ """Gets information related to the storage account in which the blob resides.
+
+ The information can also be retrieved if the user has a SAS to a container or blob.
+ The keys in the returned dictionary include 'sku_name' and 'account_kind'.
+
+ :returns: A dict of account information (SKU and account type).
+ :rtype: dict(str, str)
+ """
+ try:
+ return self._client.blob.get_account_info(cls=return_response_headers, **kwargs) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _upload_blob_options( # pylint:disable=too-many-statements
+ self, data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
+ blob_type=BlobType.BlockBlob, # type: Union[str, BlobType]
+ length=None, # type: Optional[int]
+ metadata=None, # type: Optional[Dict[str, str]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ if self.require_encryption and not self.key_encryption_key:
+ raise ValueError("Encryption required but no key was provided.")
+ encryption_options = {
+ 'required': self.require_encryption,
+ 'key': self.key_encryption_key,
+ 'resolver': self.key_resolver_function,
+ }
+ if self.key_encryption_key is not None:
+ cek, iv, encryption_data = generate_blob_encryption_data(self.key_encryption_key)
+ encryption_options['cek'] = cek
+ encryption_options['vector'] = iv
+ encryption_options['data'] = encryption_data
+
+ encoding = kwargs.pop('encoding', 'UTF-8')
+ if isinstance(data, six.text_type):
+ data = data.encode(encoding) # type: ignore
+ if length is None:
+ length = get_length(data)
+ if isinstance(data, bytes):
+ data = data[:length]
+
+ if isinstance(data, bytes):
+ stream = BytesIO(data)
+ elif hasattr(data, 'read'):
+ stream = data
+ elif hasattr(data, '__iter__'):
+ stream = IterStreamer(data, encoding=encoding)
+ else:
+ raise TypeError("Unsupported data type: {}".format(type(data)))
+
+ validate_content = kwargs.pop('validate_content', False)
+ content_settings = kwargs.pop('content_settings', None)
+ overwrite = kwargs.pop('overwrite', False)
+ max_concurrency = kwargs.pop('max_concurrency', 1)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+ kwargs['cpk_info'] = cpk_info
+
+ headers = kwargs.pop('headers', {})
+ headers.update(add_metadata_headers(metadata))
+ kwargs['lease_access_conditions'] = get_access_conditions(kwargs.pop('lease', None))
+ kwargs['modified_access_conditions'] = get_modify_conditions(kwargs)
+ kwargs['cpk_scope_info'] = get_cpk_scope_info(kwargs)
+ if content_settings:
+ kwargs['blob_headers'] = BlobHTTPHeaders(
+ blob_cache_control=content_settings.cache_control,
+ blob_content_type=content_settings.content_type,
+ blob_content_md5=content_settings.content_md5,
+ blob_content_encoding=content_settings.content_encoding,
+ blob_content_language=content_settings.content_language,
+ blob_content_disposition=content_settings.content_disposition
+ )
+ kwargs['blob_tags_string'] = serialize_blob_tags_header(kwargs.pop('tags', None))
+ kwargs['stream'] = stream
+ kwargs['length'] = length
+ kwargs['overwrite'] = overwrite
+ kwargs['headers'] = headers
+ kwargs['validate_content'] = validate_content
+ kwargs['blob_settings'] = self._config
+ kwargs['max_concurrency'] = max_concurrency
+ kwargs['encryption_options'] = encryption_options
+
+ if blob_type == BlobType.BlockBlob:
+ kwargs['client'] = self._client.block_blob
+ kwargs['data'] = data
+ elif blob_type == BlobType.PageBlob:
+ kwargs['client'] = self._client.page_blob
+ elif blob_type == BlobType.AppendBlob:
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+ kwargs['client'] = self._client.append_blob
+ else:
+ raise ValueError("Unsupported BlobType: {}".format(blob_type))
+ return kwargs
+
+ def _upload_blob_from_url_options(self, source_url, **kwargs):
+ # type: (...) -> Dict[str, Any]
+ tier = kwargs.pop('standard_blob_tier', None)
+ overwrite = kwargs.pop('overwrite', False)
+ content_settings = kwargs.pop('content_settings', None)
+ source_authorization = kwargs.pop('source_authorization', None)
+ if content_settings:
+ kwargs['blob_http_headers'] = BlobHTTPHeaders(
+ blob_cache_control=content_settings.cache_control,
+ blob_content_type=content_settings.content_type,
+ blob_content_md5=None,
+ blob_content_encoding=content_settings.content_encoding,
+ blob_content_language=content_settings.content_language,
+ blob_content_disposition=content_settings.content_disposition
+ )
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ options = {
+ 'copy_source_authorization': source_authorization,
+ 'content_length': 0,
+ 'copy_source_blob_properties': kwargs.pop('include_source_blob_properties', True),
+ 'source_content_md5': kwargs.pop('source_content_md5', None),
+ 'copy_source': source_url,
+ 'modified_access_conditions': get_modify_conditions(kwargs),
+ 'blob_tags_string': serialize_blob_tags_header(kwargs.pop('tags', None)),
+ 'cls': return_response_headers,
+ 'lease_access_conditions': get_access_conditions(kwargs.pop('destination_lease', None)),
+ 'tier': tier.value if tier else None,
+ 'source_modified_access_conditions': get_source_conditions(kwargs),
+ 'cpk_info': cpk_info,
+ 'cpk_scope_info': get_cpk_scope_info(kwargs)
+ }
+ options.update(kwargs)
+ if not overwrite and not _any_conditions(**options): # pylint: disable=protected-access
+ options['modified_access_conditions'].if_none_match = '*'
+ return options
+
+ @distributed_trace
+ def upload_blob_from_url(self, source_url, **kwargs):
+ # type: (str, Any) -> Dict[str, Any]
+ """
+ Creates a new Block Blob where the content of the blob is read from a given URL.
+ The content of an existing blob is overwritten with the new blob.
+
+ :param str source_url:
+ A URL of up to 2 KB in length that specifies a file or blob.
+ The value should be URL-encoded as it would appear in a request URI.
+ If the source is in another account, the source must either be public
+ or must be authenticated via a shared access signature. If the source
+ is public, no authentication is required.
+ Examples:
+ https://myaccount.blob.core.windows.net/mycontainer/myblob
+
+ https://myaccount.blob.core.windows.net/mycontainer/myblob?snapshot=
+
+ https://otheraccount.blob.core.windows.net/mycontainer/myblob?sastoken
+ :keyword bool overwrite: Whether the blob to be uploaded should overwrite the current data.
+ If True, upload_blob will overwrite the existing data. If set to False, the
+ operation will fail with ResourceExistsError.
+ :keyword bool include_source_blob_properties:
+ Indicates if properties from the source blob should be copied. Defaults to True.
+ :keyword tags:
+ Name-value pairs associated with the blob as tag. Tags are case-sensitive.
+ The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
+ and tag values must be between 0 and 256 characters.
+ Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
+ space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
+ :paramtype tags: dict(str, str)
+ :keyword bytearray source_content_md5:
+ Specify the md5 that is used to verify the integrity of the source bytes.
+ :keyword ~datetime.datetime source_if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the source resource has been modified since the specified time.
+ :keyword ~datetime.datetime source_if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the source resource has not been modified since the specified date/time.
+ :keyword str source_etag:
+ The source ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions source_match_condition:
+ The source match condition to use upon the etag.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ The destination ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The destination match condition to use upon the etag.
+ :keyword destination_lease:
+ The lease ID specified for this header must match the lease ID of the
+ destination blob. If the request does not include the lease ID or it is not
+ valid, the operation fails with status code 412 (Precondition Failed).
+ :paramtype destination_lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :keyword ~azure.storage.blob.ContentSettings content_settings:
+ ContentSettings object used to set blob properties. Used to set content type, encoding,
+ language, disposition, md5, and cache control.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+ :keyword ~azure.storage.blob.StandardBlobTier standard_blob_tier:
+ A standard blob tier value to set the blob to. For this version of the library,
+ this is only applicable to block blobs on standard storage accounts.
+ :keyword str source_authorization:
+ Authenticate as a service principal using a client secret to access a source blob. Ensure "bearer " is
+ the prefix of the source_authorization string.
+ """
+ options = self._upload_blob_from_url_options(
+ source_url=self._encode_source_url(source_url),
+ **kwargs)
+ try:
+ return self._client.block_blob.put_blob_from_url(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def upload_blob( # pylint: disable=too-many-locals
+ self, data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
+ blob_type=BlobType.BlockBlob, # type: Union[str, BlobType]
+ length=None, # type: Optional[int]
+ metadata=None, # type: Optional[Dict[str, str]]
+ **kwargs
+ ):
+ # type: (...) -> Any
+ """Creates a new blob from a data source with automatic chunking.
+
+ :param data: The blob data to upload.
+ :param ~azure.storage.blob.BlobType blob_type: The type of the blob. This can be
+ either BlockBlob, PageBlob or AppendBlob. The default value is BlockBlob.
+ :param int length:
+ Number of bytes to read from the stream. This is optional, but
+ should be supplied for optimal performance.
+ :param metadata:
+ Name-value pairs associated with the blob as metadata.
+ :type metadata: dict(str, str)
+ :keyword tags:
+ Name-value pairs associated with the blob as tag. Tags are case-sensitive.
+ The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
+ and tag values must be between 0 and 256 characters.
+ Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
+ space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
+
+ .. versionadded:: 12.4.0
+
+ :paramtype tags: dict(str, str)
+ :keyword bool overwrite: Whether the blob to be uploaded should overwrite the current data.
+ If True, upload_blob will overwrite the existing data. If set to False, the
+ operation will fail with ResourceExistsError. The exception to the above is with Append
+ blob types: if set to False and the data already exists, an error will not be raised
+ and the data will be appended to the existing blob. If set overwrite=True, then the existing
+ append blob will be deleted, and a new one created. Defaults to False.
+ :keyword ~azure.storage.blob.ContentSettings content_settings:
+ ContentSettings object used to set blob properties. Used to set content type, encoding,
+ language, disposition, md5, and cache control.
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash for each chunk of the blob. The storage
+ service checks the hash of the content that has arrived with the hash
+ that was sent. This is primarily valuable for detecting bitflips on
+ the wire if using http instead of https, as https (the default), will
+ already validate. Note that this MD5 hash is not stored with the
+ blob. Also note that if enabled, the memory-efficient upload algorithm
+ will not be used because computing the MD5 hash requires buffering
+ entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
+ :keyword lease:
+ Required if the blob has an active lease. If specified, upload_blob only succeeds if the
+ blob's lease is active and matches this ID. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier:
+ A page blob tier value to set the blob to. The tier correlates to the size of the
+ blob and number of allowed IOPS. This is only applicable to page blobs on
+ premium storage accounts.
+ :keyword ~azure.storage.blob.StandardBlobTier standard_blob_tier:
+ A standard blob tier value to set the blob to. For this version of the library,
+ this is only applicable to block blobs on standard storage accounts.
+ :keyword ~azure.storage.blob.ImmutabilityPolicy immutability_policy:
+ Specifies the immutability policy of a blob, blob snapshot or blob version.
+ Currently this parameter of upload_blob() API is for BlockBlob only.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword bool legal_hold:
+ Specified if a legal hold should be set on the blob.
+ Currently this parameter of upload_blob() API is for BlockBlob only.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword int maxsize_condition:
+ Optional conditional header. The max length in bytes permitted for
+ the append blob. If the Append Block operation would cause the blob
+ to exceed that limit or if the blob size is already greater than the
+ value specified in this header, the request will fail with
+ MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed).
+ :keyword int max_concurrency:
+ Maximum number of parallel connections to use when the blob size exceeds
+ 64MB.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword str encoding:
+ Defaults to UTF-8.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds. This method may make
+ multiple calls to the Azure service and the timeout will apply to
+ each call individually.
+ :returns: Blob-updated property dict (Etag and last modified)
+ :rtype: dict[str, Any]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_hello_world.py
+ :start-after: [START upload_a_blob]
+ :end-before: [END upload_a_blob]
+ :language: python
+ :dedent: 12
+ :caption: Upload a blob to the container.
+ """
+ options = self._upload_blob_options(
+ data,
+ blob_type=blob_type,
+ length=length,
+ metadata=metadata,
+ **kwargs)
+ if blob_type == BlobType.BlockBlob:
+ return upload_block_blob(**options)
+ if blob_type == BlobType.PageBlob:
+ return upload_page_blob(**options)
+ return upload_append_blob(**options)
+
+ def _download_blob_options(self, offset=None, length=None, **kwargs):
+ # type: (Optional[int], Optional[int], **Any) -> Dict[str, Any]
+ if self.require_encryption and not self.key_encryption_key:
+ raise ValueError("Encryption required but no key was provided.")
+ if length is not None and offset is None:
+ raise ValueError("Offset value must not be None if length is set.")
+ if length is not None:
+ length = offset + length - 1 # Service actually uses an end-range inclusive index
+
+ validate_content = kwargs.pop('validate_content', False)
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ options = {
+ 'clients': self._client,
+ 'config': self._config,
+ 'start_range': offset,
+ 'end_range': length,
+ 'version_id': kwargs.pop('version_id', None),
+ 'validate_content': validate_content,
+ 'encryption_options': {
+ 'required': self.require_encryption,
+ 'key': self.key_encryption_key,
+ 'resolver': self.key_resolver_function},
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cpk_info': cpk_info,
+ 'cls': kwargs.pop('cls', None) or deserialize_blob_stream,
+ 'max_concurrency':kwargs.pop('max_concurrency', 1),
+ 'encoding': kwargs.pop('encoding', None),
+ 'timeout': kwargs.pop('timeout', None),
+ 'name': self.blob_name,
+ 'container': self.container_name}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def download_blob(self, offset=None, length=None, **kwargs):
+ # type: (Optional[int], Optional[int], **Any) -> StorageStreamDownloader
+ """Downloads a blob to the StorageStreamDownloader. The readall() method must
+ be used to read all the content or readinto() must be used to download the blob into
+ a stream. Using chunks() returns an iterator which allows the user to iterate over the content in chunks.
+
+ :param int offset:
+ Start of byte range to use for downloading a section of the blob.
+ Must be set if length is provided.
+ :param int length:
+ Number of bytes to read from the stream. This is optional, but
+ should be supplied for optimal performance.
+ :keyword str version_id:
+ The version id parameter is an opaque DateTime
+ value that, when present, specifies the version of the blob to download.
+
+ .. versionadded:: 12.4.0
+ This keyword argument was introduced in API version '2019-12-12'.
+
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash for each chunk of the blob. The storage
+ service checks the hash of the content that has arrived with the hash
+ that was sent. This is primarily valuable for detecting bitflips on
+ the wire if using http instead of https, as https (the default), will
+ already validate. Note that this MD5 hash is not stored with the
+ blob. Also note that if enabled, the memory-efficient upload algorithm
+ will not be used because computing the MD5 hash requires buffering
+ entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
+ :keyword lease:
+ Required if the blob has an active lease. If specified, download_blob only
+ succeeds if the blob's lease is active and matches this ID. Value can be a
+ BlobLeaseClient object or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword int max_concurrency:
+ The number of parallel connections with which to download.
+ :keyword str encoding:
+ Encoding to decode the downloaded bytes. Default is None, i.e. no decoding.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds. This method may make
+ multiple calls to the Azure service and the timeout will apply to
+ each call individually.
+ :returns: A streaming object (StorageStreamDownloader)
+ :rtype: ~azure.storage.blob.StorageStreamDownloader
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_hello_world.py
+ :start-after: [START download_a_blob]
+ :end-before: [END download_a_blob]
+ :language: python
+ :dedent: 12
+ :caption: Download a blob.
+ """
+ options = self._download_blob_options(
+ offset=offset,
+ length=length,
+ **kwargs)
+ return StorageStreamDownloader(**options)
+
+ def _quick_query_options(self, query_expression,
+ **kwargs):
+ # type: (str, **Any) -> Dict[str, Any]
+ delimiter = '\n'
+ input_format = kwargs.pop('blob_format', None)
+ if input_format == QuickQueryDialect.DelimitedJson:
+ input_format = DelimitedJsonDialect()
+ if input_format == QuickQueryDialect.DelimitedText:
+ input_format = DelimitedTextDialect()
+ input_parquet_format = input_format == "ParquetDialect"
+ if input_format and not input_parquet_format:
+ try:
+ delimiter = input_format.lineterminator
+ except AttributeError:
+ try:
+ delimiter = input_format.delimiter
+ except AttributeError:
+ raise ValueError("The Type of blob_format can only be DelimitedTextDialect or "
+ "DelimitedJsonDialect or ParquetDialect")
+ output_format = kwargs.pop('output_format', None)
+ if output_format == QuickQueryDialect.DelimitedJson:
+ output_format = DelimitedJsonDialect()
+ if output_format == QuickQueryDialect.DelimitedText:
+ output_format = DelimitedTextDialect()
+ if output_format:
+ if output_format == "ParquetDialect":
+ raise ValueError("ParquetDialect is invalid as an output format.")
+ try:
+ delimiter = output_format.lineterminator
+ except AttributeError:
+ try:
+ delimiter = output_format.delimiter
+ except AttributeError:
+ pass
+ else:
+ output_format = input_format if not input_parquet_format else None
+ query_request = QueryRequest(
+ expression=query_expression,
+ input_serialization=serialize_query_format(input_format),
+ output_serialization=serialize_query_format(output_format)
+ )
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(
+ encryption_key=cpk.key_value,
+ encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm
+ )
+ options = {
+ 'query_request': query_request,
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cpk_info': cpk_info,
+ 'snapshot': self.snapshot,
+ 'timeout': kwargs.pop('timeout', None),
+ 'cls': return_headers_and_deserialized,
+ }
+ options.update(kwargs)
+ return options, delimiter
+
+ @distributed_trace
+ def query_blob(self, query_expression, **kwargs):
+ # type: (str, **Any) -> BlobQueryReader
+ """Enables users to select/project on blob/or blob snapshot data by providing simple query expressions.
+ This operations returns a BlobQueryReader, users need to use readall() or readinto() to get query data.
+
+ :param str query_expression:
+ Required. a query statement.
+ :keyword Callable[~azure.storage.blob.BlobQueryError] on_error:
+ A function to be called on any processing errors returned by the service.
+ :keyword blob_format:
+ Optional. Defines the serialization of the data currently stored in the blob. The default is to
+ treat the blob data as CSV data formatted in the default dialect. This can be overridden with
+ a custom DelimitedTextDialect, or DelimitedJsonDialect or "ParquetDialect" (passed as a string or enum).
+ These dialects can be passed through their respective classes, the QuickQueryDialect enum or as a string
+ :paramtype blob_format: ~azure.storage.blob.DelimitedTextDialect or ~azure.storage.blob.DelimitedJsonDialect
+ or ~azure.storage.blob.QuickQueryDialect or str
+ :keyword output_format:
+ Optional. Defines the output serialization for the data stream. By default the data will be returned
+ as it is represented in the blob (Parquet formats default to DelimitedTextDialect).
+ By providing an output format, the blob data will be reformatted according to that profile.
+ This value can be a DelimitedTextDialect or a DelimitedJsonDialect or ArrowDialect.
+ These dialects can be passed through their respective classes, the QuickQueryDialect enum or as a string
+ :paramtype output_format: ~azure.storage.blob.DelimitedTextDialect or ~azure.storage.blob.DelimitedJsonDialect
+ or list[~azure.storage.blob.ArrowDialect] or ~azure.storage.blob.QuickQueryDialect or str
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: A streaming object (BlobQueryReader)
+ :rtype: ~azure.storage.blob.BlobQueryReader
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_query.py
+ :start-after: [START query]
+ :end-before: [END query]
+ :language: python
+ :dedent: 4
+ :caption: select/project on blob/or blob snapshot data by providing simple query expressions.
+ """
+ errors = kwargs.pop("on_error", None)
+ error_cls = kwargs.pop("error_cls", BlobQueryError)
+ encoding = kwargs.pop("encoding", None)
+ options, delimiter = self._quick_query_options(query_expression, **kwargs)
+ try:
+ headers, raw_response_body = self._client.blob.query(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ return BlobQueryReader(
+ name=self.blob_name,
+ container=self.container_name,
+ errors=errors,
+ record_delimiter=delimiter,
+ encoding=encoding,
+ headers=headers,
+ response=raw_response_body,
+ error_cls=error_cls)
+
+ @staticmethod
+ def _generic_delete_blob_options(delete_snapshots=None, **kwargs):
+ # type: (str, **Any) -> Dict[str, Any]
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ if delete_snapshots:
+ delete_snapshots = DeleteSnapshotsOptionType(delete_snapshots)
+ options = {
+ 'timeout': kwargs.pop('timeout', None),
+ 'snapshot': kwargs.pop('snapshot', None), # this is added for delete_blobs
+ 'delete_snapshots': delete_snapshots or None,
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions}
+ options.update(kwargs)
+ return options
+
+ def _delete_blob_options(self, delete_snapshots=None, **kwargs):
+ # type: (str, **Any) -> Dict[str, Any]
+ if self.snapshot and delete_snapshots:
+ raise ValueError("The delete_snapshots option cannot be used with a specific snapshot.")
+ options = self._generic_delete_blob_options(delete_snapshots, **kwargs)
+ options['snapshot'] = self.snapshot
+ options['version_id'] = kwargs.pop('version_id', None)
+ options['blob_delete_type'] = kwargs.pop('blob_delete_type', None)
+ return options
+
+ @distributed_trace
+ def delete_blob(self, delete_snapshots=None, **kwargs):
+ # type: (str, **Any) -> None
+ """Marks the specified blob for deletion.
+
+ The blob is later deleted during garbage collection.
+ Note that in order to delete a blob, you must delete all of its
+ snapshots. You can delete both at the same time with the delete_blob()
+ operation.
+
+ If a delete retention policy is enabled for the service, then this operation soft deletes the blob
+ and retains the blob for a specified number of days.
+ After the specified number of days, the blob's data is removed from the service during garbage collection.
+ Soft deleted blob is accessible through :func:`~ContainerClient.list_blobs()` specifying `include=['deleted']`
+ option. Soft-deleted blob can be restored using :func:`undelete` operation.
+
+ :param str delete_snapshots:
+ Required if the blob has associated snapshots. Values include:
+ - "only": Deletes only the blobs snapshots.
+ - "include": Deletes the blob along with all snapshots.
+ :keyword str version_id:
+ The version id parameter is an opaque DateTime
+ value that, when present, specifies the version of the blob to delete.
+
+ .. versionadded:: 12.4.0
+ This keyword argument was introduced in API version '2019-12-12'.
+
+ :keyword lease:
+ Required if the blob has an active lease. If specified, delete_blob only
+ succeeds if the blob's lease is active and matches this ID. Value can be a
+ BlobLeaseClient object or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: None
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_hello_world.py
+ :start-after: [START delete_blob]
+ :end-before: [END delete_blob]
+ :language: python
+ :dedent: 12
+ :caption: Delete a blob.
+ """
+ options = self._delete_blob_options(delete_snapshots=delete_snapshots, **kwargs)
+ try:
+ self._client.blob.delete(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def undelete_blob(self, **kwargs):
+ # type: (**Any) -> None
+ """Restores soft-deleted blobs or snapshots.
+
+ Operation will only be successful if used within the specified number of days
+ set in the delete retention policy.
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: None
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_common.py
+ :start-after: [START undelete_blob]
+ :end-before: [END undelete_blob]
+ :language: python
+ :dedent: 8
+ :caption: Undeleting a blob.
+ """
+ try:
+ self._client.blob.undelete(timeout=kwargs.pop('timeout', None), **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace()
+ def exists(self, **kwargs):
+ # type: (**Any) -> bool
+ """
+ Returns True if a blob exists with the defined parameters, and returns
+ False otherwise.
+
+ :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.
+ :kwarg int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: boolean
+ """
+ try:
+ self._client.blob.get_properties(
+ snapshot=self.snapshot,
+ **kwargs)
+ return True
+ # Encrypted with CPK
+ except ResourceExistsError:
+ return True
+ except HttpResponseError as error:
+ try:
+ process_storage_error(error)
+ except ResourceNotFoundError:
+ return False
+
+ @distributed_trace
+ def get_blob_properties(self, **kwargs):
+ # type: (**Any) -> BlobProperties
+ """Returns all user-defined metadata, standard HTTP properties, and
+ system properties for the blob. It does not return the content of the blob.
+
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword str version_id:
+ The version id parameter is an opaque DateTime
+ value that, when present, specifies the version of the blob to get properties.
+
+ .. versionadded:: 12.4.0
+ This keyword argument was introduced in API version '2019-12-12'.
+
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: BlobProperties
+ :rtype: ~azure.storage.blob.BlobProperties
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_common.py
+ :start-after: [START get_blob_properties]
+ :end-before: [END get_blob_properties]
+ :language: python
+ :dedent: 8
+ :caption: Getting the properties for a blob.
+ """
+ # TODO: extract this out as _get_blob_properties_options
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+ try:
+ cls_method = kwargs.pop('cls', None)
+ if cls_method:
+ kwargs['cls'] = partial(deserialize_pipeline_response_into_cls, cls_method)
+ blob_props = self._client.blob.get_properties(
+ timeout=kwargs.pop('timeout', None),
+ version_id=kwargs.pop('version_id', None),
+ snapshot=self.snapshot,
+ lease_access_conditions=access_conditions,
+ modified_access_conditions=mod_conditions,
+ cls=kwargs.pop('cls', None) or deserialize_blob_properties,
+ cpk_info=cpk_info,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ blob_props.name = self.blob_name
+ if isinstance(blob_props, BlobProperties):
+ blob_props.container = self.container_name
+ blob_props.snapshot = self.snapshot
+ return blob_props # type: ignore
+
+ def _set_http_headers_options(self, content_settings=None, **kwargs):
+ # type: (Optional[ContentSettings], **Any) -> Dict[str, Any]
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ blob_headers = None
+ if content_settings:
+ blob_headers = BlobHTTPHeaders(
+ blob_cache_control=content_settings.cache_control,
+ blob_content_type=content_settings.content_type,
+ blob_content_md5=content_settings.content_md5,
+ blob_content_encoding=content_settings.content_encoding,
+ blob_content_language=content_settings.content_language,
+ blob_content_disposition=content_settings.content_disposition
+ )
+ options = {
+ 'timeout': kwargs.pop('timeout', None),
+ 'blob_http_headers': blob_headers,
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def set_http_headers(self, content_settings=None, **kwargs):
+ # type: (Optional[ContentSettings], **Any) -> None
+ """Sets system properties on the blob.
+
+ If one property is set for the content_settings, all properties will be overridden.
+
+ :param ~azure.storage.blob.ContentSettings content_settings:
+ ContentSettings object used to set blob properties. Used to set content type, encoding,
+ language, disposition, md5, and cache control.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified)
+ :rtype: Dict[str, Any]
+ """
+ options = self._set_http_headers_options(content_settings=content_settings, **kwargs)
+ try:
+ return self._client.blob.set_http_headers(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _set_blob_metadata_options(self, metadata=None, **kwargs):
+ # type: (Optional[Dict[str, str]], **Any) -> Dict[str, Any]
+ headers = kwargs.pop('headers', {})
+ headers.update(add_metadata_headers(metadata))
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+ options = {
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers,
+ 'headers': headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def set_blob_metadata(self, metadata=None, **kwargs):
+ # type: (Optional[Dict[str, str]], **Any) -> Dict[str, Union[str, datetime]]
+ """Sets user-defined metadata for the blob as one or more name-value pairs.
+
+ :param metadata:
+ Dict containing name and value pairs. Each call to this operation
+ replaces all existing metadata attached to the blob. To remove all
+ metadata from the blob, call this operation with no metadata headers.
+ :type metadata: dict(str, str)
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified)
+ """
+ options = self._set_blob_metadata_options(metadata=metadata, **kwargs)
+ try:
+ return self._client.blob.set_metadata(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def set_immutability_policy(self, immutability_policy, **kwargs):
+ # type: (ImmutabilityPolicy, **Any) -> Dict[str, str]
+ """The Set Immutability Policy operation sets the immutability policy on the blob.
+
+ .. versionadded:: 12.10.0
+ This operation was introduced in API version '2020-10-02'.
+
+ :param ~azure.storage.blob.ImmutabilityPolicy immutability_policy:
+ Specifies the immutability policy of a blob, blob snapshot or blob version.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Key value pairs of blob tags.
+ :rtype: Dict[str, str]
+ """
+
+ kwargs['immutability_policy_expiry'] = immutability_policy.expiry_time
+ kwargs['immutability_policy_mode'] = immutability_policy.policy_mode
+ return self._client.blob.set_immutability_policy(cls=return_response_headers, **kwargs)
+
+ @distributed_trace
+ def delete_immutability_policy(self, **kwargs):
+ # type: (**Any) -> None
+ """The Delete Immutability Policy operation deletes the immutability policy on the blob.
+
+ .. versionadded:: 12.10.0
+ This operation was introduced in API version '2020-10-02'.
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Key value pairs of blob tags.
+ :rtype: Dict[str, str]
+ """
+
+ self._client.blob.delete_immutability_policy(**kwargs)
+
+ @distributed_trace
+ def set_legal_hold(self, legal_hold, **kwargs):
+ # type: (bool, **Any) -> Dict[str, Union[str, datetime, bool]]
+ """The Set Legal Hold operation sets a legal hold on the blob.
+
+ .. versionadded:: 12.10.0
+ This operation was introduced in API version '2020-10-02'.
+
+ :param bool legal_hold:
+ Specified if a legal hold should be set on the blob.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Key value pairs of blob tags.
+ :rtype: Dict[str, Union[str, datetime, bool]]
+ """
+
+ return self._client.blob.set_legal_hold(legal_hold, cls=return_response_headers, **kwargs)
+
+ def _create_page_blob_options( # type: ignore
+ self, size, # type: int
+ content_settings=None, # type: Optional[ContentSettings]
+ metadata=None, # type: Optional[Dict[str, str]]
+ premium_page_blob_tier=None, # type: Optional[Union[str, PremiumPageBlobTier]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+ headers = kwargs.pop('headers', {})
+ headers.update(add_metadata_headers(metadata))
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ blob_headers = None
+ if content_settings:
+ blob_headers = BlobHTTPHeaders(
+ blob_cache_control=content_settings.cache_control,
+ blob_content_type=content_settings.content_type,
+ blob_content_md5=content_settings.content_md5,
+ blob_content_encoding=content_settings.content_encoding,
+ blob_content_language=content_settings.content_language,
+ blob_content_disposition=content_settings.content_disposition
+ )
+
+ sequence_number = kwargs.pop('sequence_number', None)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ immutability_policy = kwargs.pop('immutability_policy', None)
+ if immutability_policy:
+ kwargs['immutability_policy_expiry'] = immutability_policy.expiry_time
+ kwargs['immutability_policy_mode'] = immutability_policy.policy_mode
+
+ if premium_page_blob_tier:
+ try:
+ headers['x-ms-access-tier'] = premium_page_blob_tier.value # type: ignore
+ except AttributeError:
+ headers['x-ms-access-tier'] = premium_page_blob_tier # type: ignore
+
+ blob_tags_string = serialize_blob_tags_header(kwargs.pop('tags', None))
+
+ options = {
+ 'content_length': 0,
+ 'blob_content_length': size,
+ 'blob_sequence_number': sequence_number,
+ 'blob_http_headers': blob_headers,
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'blob_tags_string': blob_tags_string,
+ 'cls': return_response_headers,
+ 'headers': headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def create_page_blob( # type: ignore
+ self, size, # type: int
+ content_settings=None, # type: Optional[ContentSettings]
+ metadata=None, # type: Optional[Dict[str, str]]
+ premium_page_blob_tier=None, # type: Optional[Union[str, PremiumPageBlobTier]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Union[str, datetime]]
+ """Creates a new Page Blob of the specified size.
+
+ :param int size:
+ This specifies the maximum size for the page blob, up to 1 TB.
+ The page blob size must be aligned to a 512-byte boundary.
+ :param ~azure.storage.blob.ContentSettings content_settings:
+ ContentSettings object used to set blob properties. Used to set content type, encoding,
+ language, disposition, md5, and cache control.
+ :param metadata:
+ Name-value pairs associated with the blob as metadata.
+ :type metadata: dict(str, str)
+ :param ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier:
+ A page blob tier value to set the blob to. The tier correlates to the size of the
+ blob and number of allowed IOPS. This is only applicable to page blobs on
+ premium storage accounts.
+ :keyword tags:
+ Name-value pairs associated with the blob as tag. Tags are case-sensitive.
+ The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
+ and tag values must be between 0 and 256 characters.
+ Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
+ space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
+
+ .. versionadded:: 12.4.0
+
+ :paramtype tags: dict(str, str)
+ :keyword int sequence_number:
+ Only for Page blobs. The sequence number is a user-controlled value that you can use to
+ track requests. The value of the sequence number must be between 0
+ and 2^63 - 1.The default value is 0.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~azure.storage.blob.ImmutabilityPolicy immutability_policy:
+ Specifies the immutability policy of a blob, blob snapshot or blob version.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword bool legal_hold:
+ Specified if a legal hold should be set on the blob.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified).
+ :rtype: dict[str, Any]
+ """
+ options = self._create_page_blob_options(
+ size,
+ content_settings=content_settings,
+ metadata=metadata,
+ premium_page_blob_tier=premium_page_blob_tier,
+ **kwargs)
+ try:
+ return self._client.page_blob.create(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _create_append_blob_options(self, content_settings=None, metadata=None, **kwargs):
+ # type: (Optional[ContentSettings], Optional[Dict[str, str]], **Any) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+ headers = kwargs.pop('headers', {})
+ headers.update(add_metadata_headers(metadata))
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ blob_headers = None
+ if content_settings:
+ blob_headers = BlobHTTPHeaders(
+ blob_cache_control=content_settings.cache_control,
+ blob_content_type=content_settings.content_type,
+ blob_content_md5=content_settings.content_md5,
+ blob_content_encoding=content_settings.content_encoding,
+ blob_content_language=content_settings.content_language,
+ blob_content_disposition=content_settings.content_disposition
+ )
+
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ immutability_policy = kwargs.pop('immutability_policy', None)
+ if immutability_policy:
+ kwargs['immutability_policy_expiry'] = immutability_policy.expiry_time
+ kwargs['immutability_policy_mode'] = immutability_policy.policy_mode
+
+ blob_tags_string = serialize_blob_tags_header(kwargs.pop('tags', None))
+
+ options = {
+ 'content_length': 0,
+ 'blob_http_headers': blob_headers,
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'blob_tags_string': blob_tags_string,
+ 'cls': return_response_headers,
+ 'headers': headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def create_append_blob(self, content_settings=None, metadata=None, **kwargs):
+ # type: (Optional[ContentSettings], Optional[Dict[str, str]], **Any) -> Dict[str, Union[str, datetime]]
+ """Creates a new Append Blob.
+
+ :param ~azure.storage.blob.ContentSettings content_settings:
+ ContentSettings object used to set blob properties. Used to set content type, encoding,
+ language, disposition, md5, and cache control.
+ :param metadata:
+ Name-value pairs associated with the blob as metadata.
+ :type metadata: dict(str, str)
+ :keyword tags:
+ Name-value pairs associated with the blob as tag. Tags are case-sensitive.
+ The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
+ and tag values must be between 0 and 256 characters.
+ Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
+ space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
+
+ .. versionadded:: 12.4.0
+
+ :paramtype tags: dict(str, str)
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~azure.storage.blob.ImmutabilityPolicy immutability_policy:
+ Specifies the immutability policy of a blob, blob snapshot or blob version.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword bool legal_hold:
+ Specified if a legal hold should be set on the blob.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified).
+ :rtype: dict[str, Any]
+ """
+ options = self._create_append_blob_options(
+ content_settings=content_settings,
+ metadata=metadata,
+ **kwargs)
+ try:
+ return self._client.append_blob.create(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _create_snapshot_options(self, metadata=None, **kwargs):
+ # type: (Optional[Dict[str, str]], **Any) -> Dict[str, Any]
+ headers = kwargs.pop('headers', {})
+ headers.update(add_metadata_headers(metadata))
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ options = {
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers,
+ 'headers': headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def create_snapshot(self, metadata=None, **kwargs):
+ # type: (Optional[Dict[str, str]], **Any) -> Dict[str, Union[str, datetime]]
+ """Creates a snapshot of the blob.
+
+ A snapshot is a read-only version of a blob that's taken at a point in time.
+ It can be read, copied, or deleted, but not modified. Snapshots provide a way
+ to back up a blob as it appears at a moment in time.
+
+ A snapshot of a blob has the same name as the base blob from which the snapshot
+ is taken, with a DateTime value appended to indicate the time at which the
+ snapshot was taken.
+
+ :param metadata:
+ Name-value pairs associated with the blob as metadata.
+ :type metadata: dict(str, str)
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on destination blob with a matching value.
+
+ .. versionadded:: 12.4.0
+
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Snapshot ID, Etag, and last modified).
+ :rtype: dict[str, Any]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_common.py
+ :start-after: [START create_blob_snapshot]
+ :end-before: [END create_blob_snapshot]
+ :language: python
+ :dedent: 8
+ :caption: Create a snapshot of the blob.
+ """
+ options = self._create_snapshot_options(metadata=metadata, **kwargs)
+ try:
+ return self._client.blob.create_snapshot(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _start_copy_from_url_options(self, source_url, metadata=None, incremental_copy=False, **kwargs):
+ # type: (str, Optional[Dict[str, str]], bool, **Any) -> Dict[str, Any]
+ headers = kwargs.pop('headers', {})
+ headers.update(add_metadata_headers(metadata))
+ if 'source_lease' in kwargs:
+ source_lease = kwargs.pop('source_lease')
+ try:
+ headers['x-ms-source-lease-id'] = source_lease.id # type: str
+ except AttributeError:
+ headers['x-ms-source-lease-id'] = source_lease
+
+ tier = kwargs.pop('premium_page_blob_tier', None) or kwargs.pop('standard_blob_tier', None)
+ requires_sync = kwargs.pop('requires_sync', None)
+ encryption_scope_str = kwargs.pop('encryption_scope', None)
+ source_authorization = kwargs.pop('source_authorization', None)
+
+ if not requires_sync and encryption_scope_str:
+ raise ValueError("Encryption_scope is only supported for sync copy, please specify requires_sync=True")
+ if source_authorization and incremental_copy:
+ raise ValueError("Source authorization tokens are not applicable for incremental copying.")
+ #
+ # TODO: refactor start_copy_from_url api in _blob_client.py. Call _generated/_blob_operations.py copy_from_url
+ # when requires_sync=True is set.
+ # Currently both sync copy and async copy are calling _generated/_blob_operations.py start_copy_from_url.
+ # As sync copy diverges more from async copy, more problem will surface.
+ if encryption_scope_str:
+ headers.update({'x-ms-encryption-scope': encryption_scope_str})
+
+ if requires_sync is True:
+ headers['x-ms-requires-sync'] = str(requires_sync)
+ if source_authorization:
+ headers['x-ms-copy-source-authorization'] = source_authorization
+ else:
+ if source_authorization:
+ raise ValueError("Source authorization tokens are only applicable for synchronous copy operations.")
+ timeout = kwargs.pop('timeout', None)
+ dest_mod_conditions = get_modify_conditions(kwargs)
+ blob_tags_string = serialize_blob_tags_header(kwargs.pop('tags', None))
+
+ immutability_policy = kwargs.pop('immutability_policy', None)
+ if immutability_policy:
+ kwargs['immutability_policy_expiry'] = immutability_policy.expiry_time
+ kwargs['immutability_policy_mode'] = immutability_policy.policy_mode
+
+ options = {
+ 'copy_source': source_url,
+ 'seal_blob': kwargs.pop('seal_destination_blob', None),
+ 'timeout': timeout,
+ 'modified_access_conditions': dest_mod_conditions,
+ 'blob_tags_string': blob_tags_string,
+ 'headers': headers,
+ 'cls': return_response_headers,
+ }
+ if not incremental_copy:
+ source_mod_conditions = get_source_conditions(kwargs)
+ dest_access_conditions = get_access_conditions(kwargs.pop('destination_lease', None))
+ options['source_modified_access_conditions'] = source_mod_conditions
+ options['lease_access_conditions'] = dest_access_conditions
+ options['tier'] = tier.value if tier else None
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def start_copy_from_url(self, source_url, metadata=None, incremental_copy=False, **kwargs):
+ # type: (str, Optional[Dict[str, str]], bool, **Any) -> Dict[str, Union[str, datetime]]
+ """Copies a blob asynchronously.
+
+ This operation returns a copy operation
+ object that can be used to wait on the completion of the operation,
+ as well as check status or abort the copy operation.
+ The Blob service copies blobs on a best-effort basis.
+
+ The source blob for a copy operation may be a block blob, an append blob,
+ or a page blob. If the destination blob already exists, it must be of the
+ same blob type as the source blob. Any existing destination blob will be
+ overwritten. The destination blob cannot be modified while a copy operation
+ is in progress.
+
+ When copying from a page blob, the Blob service creates a destination page
+ blob of the source blob's length, initially containing all zeroes. Then
+ the source page ranges are enumerated, and non-empty ranges are copied.
+
+ For a block blob or an append blob, the Blob service creates a committed
+ blob of zero length before returning from this operation. When copying
+ from a block blob, all committed blocks and their block IDs are copied.
+ Uncommitted blocks are not copied. At the end of the copy operation, the
+ destination blob will have the same committed block count as the source.
+
+ When copying from an append blob, all committed blocks are copied. At the
+ end of the copy operation, the destination blob will have the same committed
+ block count as the source.
+
+ For all blob types, you can call status() on the returned polling object
+ to check the status of the copy operation, or wait() to block until the
+ operation is complete. The final blob will be committed when the copy completes.
+
+ :param str source_url:
+ A URL of up to 2 KB in length that specifies a file or blob.
+ The value should be URL-encoded as it would appear in a request URI.
+ If the source is in another account, the source must either be public
+ or must be authenticated via a shared access signature. If the source
+ is public, no authentication is required.
+ Examples:
+ https://myaccount.blob.core.windows.net/mycontainer/myblob
+
+ https://myaccount.blob.core.windows.net/mycontainer/myblob?snapshot=
+
+ https://otheraccount.blob.core.windows.net/mycontainer/myblob?sastoken
+ :param metadata:
+ Name-value pairs associated with the blob as metadata. If no name-value
+ pairs are specified, the operation will copy the metadata from the
+ source blob or file to the destination blob. If one or more name-value
+ pairs are specified, the destination blob is created with the specified
+ metadata, and metadata is not copied from the source blob or file.
+ :type metadata: dict(str, str)
+ :param bool incremental_copy:
+ Copies the snapshot of the source page blob to a destination page blob.
+ The snapshot is copied such that only the differential changes between
+ the previously copied snapshot are transferred to the destination.
+ The copied snapshots are complete copies of the original snapshot and
+ can be read or copied from as usual. Defaults to False.
+ :keyword tags:
+ Name-value pairs associated with the blob as tag. Tags are case-sensitive.
+ The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
+ and tag values must be between 0 and 256 characters.
+ Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
+ space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
+
+ .. versionadded:: 12.4.0
+
+ :paramtype tags: dict(str, str)
+ :keyword ~azure.storage.blob.ImmutabilityPolicy immutability_policy:
+ Specifies the immutability policy of a blob, blob snapshot or blob version.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword bool legal_hold:
+ Specified if a legal hold should be set on the blob.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword ~datetime.datetime source_if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this conditional header to copy the blob only if the source
+ blob has been modified since the specified date/time.
+ :keyword ~datetime.datetime source_if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this conditional header to copy the blob only if the source blob
+ has not been modified since the specified date/time.
+ :keyword str source_etag:
+ The source ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions source_match_condition:
+ The source match condition to use upon the etag.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this conditional header to copy the blob only
+ if the destination blob has been modified since the specified date/time.
+ If the destination blob has not been modified, the Blob service returns
+ status code 412 (Precondition Failed).
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this conditional header to copy the blob only
+ if the destination blob has not been modified since the specified
+ date/time. If the destination blob has been modified, the Blob service
+ returns status code 412 (Precondition Failed).
+ :keyword str etag:
+ The destination ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The destination match condition to use upon the etag.
+ :keyword destination_lease:
+ The lease ID specified for this header must match the lease ID of the
+ destination blob. If the request does not include the lease ID or it is not
+ valid, the operation fails with status code 412 (Precondition Failed).
+ :paramtype destination_lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword source_lease:
+ Specify this to perform the Copy Blob operation only if
+ the lease ID given matches the active lease ID of the source blob.
+ :paramtype source_lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier:
+ A page blob tier value to set the blob to. The tier correlates to the size of the
+ blob and number of allowed IOPS. This is only applicable to page blobs on
+ premium storage accounts.
+ :keyword ~azure.storage.blob.StandardBlobTier standard_blob_tier:
+ A standard blob tier value to set the blob to. For this version of the library,
+ this is only applicable to block blobs on standard storage accounts.
+ :keyword ~azure.storage.blob.RehydratePriority rehydrate_priority:
+ Indicates the priority with which to rehydrate an archived blob
+ :keyword bool seal_destination_blob:
+ Seal the destination append blob. This operation is only for append blob.
+
+ .. versionadded:: 12.4.0
+
+ :keyword bool requires_sync:
+ Enforces that the service will not return a response until the copy is complete.
+ :keyword str source_authorization:
+ Authenticate as a service principal using a client secret to access a source blob. Ensure "bearer " is
+ the prefix of the source_authorization string. This option is only available when `incremental_copy` is
+ set to False and `requires_sync` is set to True.
+
+ .. versionadded:: 12.9.0
+
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the sync copied blob. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.10.0
+
+ :returns: A dictionary of copy properties (etag, last_modified, copy_id, copy_status).
+ :rtype: dict[str, Union[str, ~datetime.datetime]]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_common.py
+ :start-after: [START copy_blob_from_url]
+ :end-before: [END copy_blob_from_url]
+ :language: python
+ :dedent: 12
+ :caption: Copy a blob from a URL.
+ """
+ options = self._start_copy_from_url_options(
+ source_url=self._encode_source_url(source_url),
+ metadata=metadata,
+ incremental_copy=incremental_copy,
+ **kwargs)
+ try:
+ if incremental_copy:
+ return self._client.page_blob.copy_incremental(**options)
+ return self._client.blob.start_copy_from_url(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _abort_copy_options(self, copy_id, **kwargs):
+ # type: (Union[str, Dict[str, Any], BlobProperties], **Any) -> Dict[str, Any]
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ try:
+ copy_id = copy_id.copy.id
+ except AttributeError:
+ try:
+ copy_id = copy_id['copy_id']
+ except TypeError:
+ pass
+ options = {
+ 'copy_id': copy_id,
+ 'lease_access_conditions': access_conditions,
+ 'timeout': kwargs.pop('timeout', None)}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def abort_copy(self, copy_id, **kwargs):
+ # type: (Union[str, Dict[str, Any], BlobProperties], **Any) -> None
+ """Abort an ongoing copy operation.
+
+ This will leave a destination blob with zero length and full metadata.
+ This will raise an error if the copy operation has already ended.
+
+ :param copy_id:
+ The copy operation to abort. This can be either an ID string, or an
+ instance of BlobProperties.
+ :type copy_id: str or ~azure.storage.blob.BlobProperties
+ :rtype: None
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_common.py
+ :start-after: [START abort_copy_blob_from_url]
+ :end-before: [END abort_copy_blob_from_url]
+ :language: python
+ :dedent: 12
+ :caption: Abort copying a blob from URL.
+ """
+ options = self._abort_copy_options(copy_id, **kwargs)
+ try:
+ self._client.blob.abort_copy_from_url(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def acquire_lease(self, lease_duration=-1, lease_id=None, **kwargs):
+ # type: (int, Optional[str], **Any) -> BlobLeaseClient
+ """Requests a new lease.
+
+ If the blob does not have an active lease, the Blob
+ Service creates a lease on the blob and returns a new lease.
+
+ :param int lease_duration:
+ Specifies the duration of the lease, in seconds, or negative one
+ (-1) for a lease that never expires. A non-infinite lease can be
+ between 15 and 60 seconds. A lease duration cannot be changed
+ using renew or change. Default is -1 (infinite lease).
+ :param str lease_id:
+ Proposed lease ID, in a GUID string format. The Blob Service
+ returns 400 (Invalid request) if the proposed lease ID is not
+ in the correct format.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: A BlobLeaseClient object.
+ :rtype: ~azure.storage.blob.BlobLeaseClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_common.py
+ :start-after: [START acquire_lease_on_blob]
+ :end-before: [END acquire_lease_on_blob]
+ :language: python
+ :dedent: 8
+ :caption: Acquiring a lease on a blob.
+ """
+ lease = BlobLeaseClient(self, lease_id=lease_id) # type: ignore
+ lease.acquire(lease_duration=lease_duration, **kwargs)
+ return lease
+
+ @distributed_trace
+ def set_standard_blob_tier(self, standard_blob_tier, **kwargs):
+ # type: (Union[str, StandardBlobTier], Any) -> None
+ """This operation sets the tier on a block blob.
+
+ A block blob's tier determines Hot/Cool/Archive storage type.
+ This operation does not update the blob's ETag.
+
+ :param standard_blob_tier:
+ Indicates the tier to be set on the blob. Options include 'Hot', 'Cool',
+ 'Archive'. The hot tier is optimized for storing data that is accessed
+ frequently. The cool storage tier is optimized for storing data that
+ is infrequently accessed and stored for at least a month. The archive
+ tier is optimized for storing data that is rarely accessed and stored
+ for at least six months with flexible latency requirements.
+ :type standard_blob_tier: str or ~azure.storage.blob.StandardBlobTier
+ :keyword ~azure.storage.blob.RehydratePriority rehydrate_priority:
+ Indicates the priority with which to rehydrate an archived blob
+ :keyword str version_id:
+ The version id parameter is an opaque DateTime
+ value that, when present, specifies the version of the blob to download.
+
+ .. versionadded:: 12.4.0
+ This keyword argument was introduced in API version '2019-12-12'.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :rtype: None
+ """
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ if standard_blob_tier is None:
+ raise ValueError("A StandardBlobTier must be specified")
+ if self.snapshot and kwargs.get('version_id'):
+ raise ValueError("Snapshot and version_id cannot be set at the same time")
+ try:
+ self._client.blob.set_tier(
+ tier=standard_blob_tier,
+ snapshot=self.snapshot,
+ timeout=kwargs.pop('timeout', None),
+ modified_access_conditions=mod_conditions,
+ lease_access_conditions=access_conditions,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _stage_block_options(
+ self, block_id, # type: str
+ data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
+ length=None, # type: Optional[int]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+ block_id = encode_base64(str(block_id))
+ if isinstance(data, six.text_type):
+ data = data.encode(kwargs.pop('encoding', 'UTF-8')) # type: ignore
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ if length is None:
+ length = get_length(data)
+ if length is None:
+ length, data = read_length(data)
+ if isinstance(data, bytes):
+ data = data[:length]
+
+ validate_content = kwargs.pop('validate_content', False)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ options = {
+ 'block_id': block_id,
+ 'content_length': length,
+ 'body': data,
+ 'transactional_content_md5': None,
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'validate_content': validate_content,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers,
+ }
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def stage_block(
+ self, block_id, # type: str
+ data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
+ length=None, # type: Optional[int]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ """Creates a new block to be committed as part of a blob.
+
+ :param str block_id: A string value that identifies the block.
+ The string should be less than or equal to 64 bytes in size.
+ For a given blob, the block_id must be the same size for each block.
+ :param data: The blob data.
+ :param int length: Size of the block.
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash for each chunk of the blob. The storage
+ service checks the hash of the content that has arrived with the hash
+ that was sent. This is primarily valuable for detecting bitflips on
+ the wire if using http instead of https, as https (the default), will
+ already validate. Note that this MD5 hash is not stored with the
+ blob. Also note that if enabled, the memory-efficient upload algorithm
+ will not be used because computing the MD5 hash requires buffering
+ entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword str encoding:
+ Defaults to UTF-8.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob property dict.
+ :rtype: dict[str, Any]
+ """
+ options = self._stage_block_options(
+ block_id,
+ data,
+ length=length,
+ **kwargs)
+ try:
+ return self._client.block_blob.stage_block(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _stage_block_from_url_options(
+ self, block_id, # type: str
+ source_url, # type: str
+ source_offset=None, # type: Optional[int]
+ source_length=None, # type: Optional[int]
+ source_content_md5=None, # type: Optional[Union[bytes, bytearray]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ source_authorization = kwargs.pop('source_authorization', None)
+ if source_length is not None and source_offset is None:
+ raise ValueError("Source offset value must not be None if length is set.")
+ if source_length is not None:
+ source_length = source_offset + source_length - 1
+ block_id = encode_base64(str(block_id))
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ range_header = None
+ if source_offset is not None:
+ range_header, _ = validate_and_format_range_headers(source_offset, source_length)
+
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+ options = {
+ 'copy_source_authorization': source_authorization,
+ 'block_id': block_id,
+ 'content_length': 0,
+ 'source_url': source_url,
+ 'source_range': range_header,
+ 'source_content_md5': bytearray(source_content_md5) if source_content_md5 else None,
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers,
+ }
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def stage_block_from_url(
+ self, block_id, # type: Union[str, int]
+ source_url, # type: str
+ source_offset=None, # type: Optional[int]
+ source_length=None, # type: Optional[int]
+ source_content_md5=None, # type: Optional[Union[bytes, bytearray]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ """Creates a new block to be committed as part of a blob where
+ the contents are read from a URL.
+
+ :param str block_id: A string value that identifies the block.
+ The string should be less than or equal to 64 bytes in size.
+ For a given blob, the block_id must be the same size for each block.
+ :param str source_url: The URL.
+ :param int source_offset:
+ Start of byte range to use for the block.
+ Must be set if source length is provided.
+ :param int source_length: The size of the block in bytes.
+ :param bytearray source_content_md5:
+ Specify the md5 calculated for the range of
+ bytes that must be read from the copy source.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :keyword str source_authorization:
+ Authenticate as a service principal using a client secret to access a source blob. Ensure "bearer " is
+ the prefix of the source_authorization string.
+ :returns: Blob property dict.
+ :rtype: dict[str, Any]
+ """
+ options = self._stage_block_from_url_options(
+ block_id,
+ source_url=self._encode_source_url(source_url),
+ source_offset=source_offset,
+ source_length=source_length,
+ source_content_md5=source_content_md5,
+ **kwargs)
+ try:
+ return self._client.block_blob.stage_block_from_url(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _get_block_list_result(self, blocks):
+ # type: (BlockList) -> Tuple[List[BlobBlock], List[BlobBlock]]
+ committed = [] # type: List
+ uncommitted = [] # type: List
+ if blocks.committed_blocks:
+ committed = [BlobBlock._from_generated(b) for b in blocks.committed_blocks] # pylint: disable=protected-access
+ if blocks.uncommitted_blocks:
+ uncommitted = [BlobBlock._from_generated(b) for b in blocks.uncommitted_blocks] # pylint: disable=protected-access
+ return committed, uncommitted
+
+ @distributed_trace
+ def get_block_list(self, block_list_type="committed", **kwargs):
+ # type: (Optional[str], **Any) -> Tuple[List[BlobBlock], List[BlobBlock]]
+ """The Get Block List operation retrieves the list of blocks that have
+ been uploaded as part of a block blob.
+
+ :param str block_list_type:
+ Specifies whether to return the list of committed
+ blocks, the list of uncommitted blocks, or both lists together.
+ Possible values include: 'committed', 'uncommitted', 'all'
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on destination blob with a matching value.
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: A tuple of two lists - committed and uncommitted blocks
+ :rtype: tuple(list(~azure.storage.blob.BlobBlock), list(~azure.storage.blob.BlobBlock))
+ """
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ try:
+ blocks = self._client.block_blob.get_block_list(
+ list_type=block_list_type,
+ snapshot=self.snapshot,
+ timeout=kwargs.pop('timeout', None),
+ lease_access_conditions=access_conditions,
+ modified_access_conditions=mod_conditions,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ return self._get_block_list_result(blocks)
+
+ def _commit_block_list_options( # type: ignore
+ self, block_list, # type: List[BlobBlock]
+ content_settings=None, # type: Optional[ContentSettings]
+ metadata=None, # type: Optional[Dict[str, str]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+ block_lookup = BlockLookupList(committed=[], uncommitted=[], latest=[])
+ for block in block_list:
+ try:
+ if block.state.value == 'committed':
+ block_lookup.committed.append(encode_base64(str(block.id)))
+ elif block.state.value == 'uncommitted':
+ block_lookup.uncommitted.append(encode_base64(str(block.id)))
+ else:
+ block_lookup.latest.append(encode_base64(str(block.id)))
+ except AttributeError:
+ block_lookup.latest.append(encode_base64(str(block)))
+ headers = kwargs.pop('headers', {})
+ headers.update(add_metadata_headers(metadata))
+ blob_headers = None
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ if content_settings:
+ blob_headers = BlobHTTPHeaders(
+ blob_cache_control=content_settings.cache_control,
+ blob_content_type=content_settings.content_type,
+ blob_content_md5=content_settings.content_md5,
+ blob_content_encoding=content_settings.content_encoding,
+ blob_content_language=content_settings.content_language,
+ blob_content_disposition=content_settings.content_disposition
+ )
+
+ validate_content = kwargs.pop('validate_content', False)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ immutability_policy = kwargs.pop('immutability_policy', None)
+ if immutability_policy:
+ kwargs['immutability_policy_expiry'] = immutability_policy.expiry_time
+ kwargs['immutability_policy_mode'] = immutability_policy.policy_mode
+
+ tier = kwargs.pop('standard_blob_tier', None)
+ blob_tags_string = serialize_blob_tags_header(kwargs.pop('tags', None))
+
+ options = {
+ 'blocks': block_lookup,
+ 'blob_http_headers': blob_headers,
+ 'lease_access_conditions': access_conditions,
+ 'timeout': kwargs.pop('timeout', None),
+ 'modified_access_conditions': mod_conditions,
+ 'cls': return_response_headers,
+ 'validate_content': validate_content,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'tier': tier.value if tier else None,
+ 'blob_tags_string': blob_tags_string,
+ 'headers': headers
+ }
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def commit_block_list( # type: ignore
+ self, block_list, # type: List[BlobBlock]
+ content_settings=None, # type: Optional[ContentSettings]
+ metadata=None, # type: Optional[Dict[str, str]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Union[str, datetime]]
+ """The Commit Block List operation writes a blob by specifying the list of
+ block IDs that make up the blob.
+
+ :param list block_list:
+ List of Blockblobs.
+ :param ~azure.storage.blob.ContentSettings content_settings:
+ ContentSettings object used to set blob properties. Used to set content type, encoding,
+ language, disposition, md5, and cache control.
+ :param metadata:
+ Name-value pairs associated with the blob as metadata.
+ :type metadata: dict[str, str]
+ :keyword tags:
+ Name-value pairs associated with the blob as tag. Tags are case-sensitive.
+ The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
+ and tag values must be between 0 and 256 characters.
+ Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
+ space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
+
+ .. versionadded:: 12.4.0
+
+ :paramtype tags: dict(str, str)
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~azure.storage.blob.ImmutabilityPolicy immutability_policy:
+ Specifies the immutability policy of a blob, blob snapshot or blob version.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword bool legal_hold:
+ Specified if a legal hold should be set on the blob.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash of the page content. The storage
+ service checks the hash of the content that has arrived
+ with the hash that was sent. This is primarily valuable for detecting
+ bitflips on the wire if using http instead of https, as https (the default),
+ will already validate. Note that this MD5 hash is not stored with the
+ blob.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on destination blob with a matching value.
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.StandardBlobTier standard_blob_tier:
+ A standard blob tier value to set the blob to. For this version of the library,
+ this is only applicable to block blobs on standard storage accounts.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified).
+ :rtype: dict(str, Any)
+ """
+ options = self._commit_block_list_options(
+ block_list,
+ content_settings=content_settings,
+ metadata=metadata,
+ **kwargs)
+ try:
+ return self._client.block_blob.commit_block_list(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def set_premium_page_blob_tier(self, premium_page_blob_tier, **kwargs):
+ # type: (Union[str, PremiumPageBlobTier], **Any) -> None
+ """Sets the page blob tiers on the blob. This API is only supported for page blobs on premium accounts.
+
+ :param premium_page_blob_tier:
+ A page blob tier value to set the blob to. The tier correlates to the size of the
+ blob and number of allowed IOPS. This is only applicable to page blobs on
+ premium storage accounts.
+ :type premium_page_blob_tier: ~azure.storage.blob.PremiumPageBlobTier
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds. This method may make
+ multiple calls to the Azure service and the timeout will apply to
+ each call individually.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :rtype: None
+ """
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ if premium_page_blob_tier is None:
+ raise ValueError("A PremiumPageBlobTier must be specified")
+ try:
+ self._client.blob.set_tier(
+ tier=premium_page_blob_tier,
+ timeout=kwargs.pop('timeout', None),
+ lease_access_conditions=access_conditions,
+ modified_access_conditions=mod_conditions,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _set_blob_tags_options(self, tags=None, **kwargs):
+ # type: (Optional[Dict[str, str]], **Any) -> Dict[str, Any]
+ tags = serialize_blob_tags(tags)
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+
+ options = {
+ 'tags': tags,
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def set_blob_tags(self, tags=None, **kwargs):
+ # type: (Optional[Dict[str, str]], **Any) -> Dict[str, Any]
+ """The Set Tags operation enables users to set tags on a blob or specific blob version, but not snapshot.
+ Each call to this operation replaces all existing tags attached to the blob. To remove all
+ tags from the blob, call this operation with no tags set.
+
+ .. versionadded:: 12.4.0
+ This operation was introduced in API version '2019-12-12'.
+
+ :param tags:
+ Name-value pairs associated with the blob as tag. Tags are case-sensitive.
+ The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
+ and tag values must be between 0 and 256 characters.
+ Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
+ space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
+ :type tags: dict(str, str)
+ :keyword str version_id:
+ The version id parameter is an opaque DateTime
+ value that, when present, specifies the version of the blob to add tags to.
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash of the tags content. The storage
+ service checks the hash of the content that has arrived
+ with the hash that was sent. This is primarily valuable for detecting
+ bitflips on the wire if using http instead of https, as https (the default),
+ will already validate. Note that this MD5 hash is not stored with the
+ blob.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on destination blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified)
+ :rtype: Dict[str, Any]
+ """
+ options = self._set_blob_tags_options(tags=tags, **kwargs)
+ try:
+ return self._client.blob.set_tags(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _get_blob_tags_options(self, **kwargs):
+ # type: (**Any) -> Dict[str, str]
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+
+ options = {
+ 'version_id': kwargs.pop('version_id', None),
+ 'snapshot': self.snapshot,
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'timeout': kwargs.pop('timeout', None),
+ 'cls': return_headers_and_deserialized}
+ return options
+
+ @distributed_trace
+ def get_blob_tags(self, **kwargs):
+ # type: (**Any) -> Dict[str, str]
+ """The Get Tags operation enables users to get tags on a blob or specific blob version, or snapshot.
+
+ .. versionadded:: 12.4.0
+ This operation was introduced in API version '2019-12-12'.
+
+ :keyword str version_id:
+ The version id parameter is an opaque DateTime
+ value that, when present, specifies the version of the blob to add tags to.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on destination blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Key value pairs of blob tags.
+ :rtype: Dict[str, str]
+ """
+ options = self._get_blob_tags_options(**kwargs)
+ try:
+ _, tags = self._client.blob.get_tags(**options)
+ return parse_tags(tags) # pylint: disable=protected-access
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _get_page_ranges_options( # type: ignore
+ self, offset=None, # type: Optional[int]
+ length=None, # type: Optional[int]
+ previous_snapshot_diff=None, # type: Optional[Union[str, Dict[str, Any]]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ if length is not None and offset is None:
+ raise ValueError("Offset value must not be None if length is set.")
+ if length is not None:
+ length = offset + length - 1 # Reformat to an inclusive range index
+ page_range, _ = validate_and_format_range_headers(
+ offset, length, start_range_required=False, end_range_required=False, align_to_page=True
+ )
+ options = {
+ 'snapshot': self.snapshot,
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'timeout': kwargs.pop('timeout', None),
+ 'range': page_range}
+ if previous_snapshot_diff:
+ try:
+ options['prevsnapshot'] = previous_snapshot_diff.snapshot # type: ignore
+ except AttributeError:
+ try:
+ options['prevsnapshot'] = previous_snapshot_diff['snapshot'] # type: ignore
+ except TypeError:
+ options['prevsnapshot'] = previous_snapshot_diff
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def get_page_ranges( # type: ignore
+ self, offset=None, # type: Optional[int]
+ length=None, # type: Optional[int]
+ previous_snapshot_diff=None, # type: Optional[Union[str, Dict[str, Any]]]
+ **kwargs
+ ):
+ # type: (...) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]
+ """Returns the list of valid page ranges for a Page Blob or snapshot
+ of a page blob.
+
+ :param int offset:
+ Start of byte range to use for getting valid page ranges.
+ If no length is given, all bytes after the offset will be searched.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :param int length:
+ Number of bytes to use for getting valid page ranges.
+ If length is given, offset must be provided.
+ This range will return valid page ranges from the offset start up to
+ the specified length.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :param str previous_snapshot_diff:
+ The snapshot diff parameter that contains an opaque DateTime value that
+ specifies a previous blob snapshot to be compared
+ against a more recent snapshot or the current blob.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns:
+ A tuple of two lists of page ranges as dictionaries with 'start' and 'end' keys.
+ The first element are filled page ranges, the 2nd element is cleared page ranges.
+ :rtype: tuple(list(dict(str, str), list(dict(str, str))
+ """
+ options = self._get_page_ranges_options(
+ offset=offset,
+ length=length,
+ previous_snapshot_diff=previous_snapshot_diff,
+ **kwargs)
+ try:
+ if previous_snapshot_diff:
+ ranges = self._client.page_blob.get_page_ranges_diff(**options)
+ else:
+ ranges = self._client.page_blob.get_page_ranges(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ return get_page_ranges_result(ranges)
+
+ @distributed_trace
+ def get_page_range_diff_for_managed_disk(
+ self, previous_snapshot_url, # type: str
+ offset=None, # type: Optional[int]
+ length=None, # type: Optional[int]
+ **kwargs
+ ):
+ # type: (...) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]
+ """Returns the list of valid page ranges for a managed disk or snapshot.
+
+ .. note::
+ This operation is only available for managed disk accounts.
+
+ .. versionadded:: 12.2.0
+ This operation was introduced in API version '2019-07-07'.
+
+ :param previous_snapshot_url:
+ Specifies the URL of a previous snapshot of the managed disk.
+ The response will only contain pages that were changed between the target blob and
+ its previous snapshot.
+ :param int offset:
+ Start of byte range to use for getting valid page ranges.
+ If no length is given, all bytes after the offset will be searched.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :param int length:
+ Number of bytes to use for getting valid page ranges.
+ If length is given, offset must be provided.
+ This range will return valid page ranges from the offset start up to
+ the specified length.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns:
+ A tuple of two lists of page ranges as dictionaries with 'start' and 'end' keys.
+ The first element are filled page ranges, the 2nd element is cleared page ranges.
+ :rtype: tuple(list(dict(str, str), list(dict(str, str))
+ """
+ options = self._get_page_ranges_options(
+ offset=offset,
+ length=length,
+ prev_snapshot_url=previous_snapshot_url,
+ **kwargs)
+ try:
+ ranges = self._client.page_blob.get_page_ranges_diff(**options)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ return get_page_ranges_result(ranges)
+
+ def _set_sequence_number_options(self, sequence_number_action, sequence_number=None, **kwargs):
+ # type: (Union[str, SequenceNumberAction], Optional[str], **Any) -> Dict[str, Any]
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ if sequence_number_action is None:
+ raise ValueError("A sequence number action must be specified")
+ options = {
+ 'sequence_number_action': sequence_number_action,
+ 'timeout': kwargs.pop('timeout', None),
+ 'blob_sequence_number': sequence_number,
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def set_sequence_number(self, sequence_number_action, sequence_number=None, **kwargs):
+ # type: (Union[str, SequenceNumberAction], Optional[str], **Any) -> Dict[str, Union[str, datetime]]
+ """Sets the blob sequence number.
+
+ :param str sequence_number_action:
+ This property indicates how the service should modify the blob's sequence
+ number. See :class:`~azure.storage.blob.SequenceNumberAction` for more information.
+ :param str sequence_number:
+ This property sets the blob's sequence number. The sequence number is a
+ user-controlled property that you can use to track requests and manage
+ concurrency issues.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified).
+ :rtype: dict(str, Any)
+ """
+ options = self._set_sequence_number_options(
+ sequence_number_action, sequence_number=sequence_number, **kwargs)
+ try:
+ return self._client.page_blob.update_sequence_number(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _resize_blob_options(self, size, **kwargs):
+ # type: (int, **Any) -> Dict[str, Any]
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ if size is None:
+ raise ValueError("A content length must be specified for a Page Blob.")
+
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+ options = {
+ 'blob_content_length': size,
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def resize_blob(self, size, **kwargs):
+ # type: (int, **Any) -> Dict[str, Union[str, datetime]]
+ """Resizes a page blob to the specified size.
+
+ If the specified value is less than the current size of the blob,
+ then all pages above the specified value are cleared.
+
+ :param int size:
+ Size used to resize blob. Maximum size for a page blob is up to 1 TB.
+ The page blob size must be aligned to a 512-byte boundary.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier:
+ A page blob tier value to set the blob to. The tier correlates to the size of the
+ blob and number of allowed IOPS. This is only applicable to page blobs on
+ premium storage accounts.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified).
+ :rtype: dict(str, Any)
+ """
+ options = self._resize_blob_options(size, **kwargs)
+ try:
+ return self._client.page_blob.resize(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _upload_page_options( # type: ignore
+ self, page, # type: bytes
+ offset, # type: int
+ length, # type: int
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ if isinstance(page, six.text_type):
+ page = page.encode(kwargs.pop('encoding', 'UTF-8'))
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+
+ if offset is None or offset % 512 != 0:
+ raise ValueError("offset must be an integer that aligns with 512 page size")
+ if length is None or length % 512 != 0:
+ raise ValueError("length must be an integer that aligns with 512 page size")
+ end_range = offset + length - 1 # Reformat to an inclusive range index
+ content_range = 'bytes={0}-{1}'.format(offset, end_range) # type: ignore
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ seq_conditions = SequenceNumberAccessConditions(
+ if_sequence_number_less_than_or_equal_to=kwargs.pop('if_sequence_number_lte', None),
+ if_sequence_number_less_than=kwargs.pop('if_sequence_number_lt', None),
+ if_sequence_number_equal_to=kwargs.pop('if_sequence_number_eq', None)
+ )
+ mod_conditions = get_modify_conditions(kwargs)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ validate_content = kwargs.pop('validate_content', False)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+ options = {
+ 'body': page[:length],
+ 'content_length': length,
+ 'transactional_content_md5': None,
+ 'timeout': kwargs.pop('timeout', None),
+ 'range': content_range,
+ 'lease_access_conditions': access_conditions,
+ 'sequence_number_access_conditions': seq_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'validate_content': validate_content,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def upload_page( # type: ignore
+ self, page, # type: bytes
+ offset, # type: int
+ length, # type: int
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Union[str, datetime]]
+ """The Upload Pages operation writes a range of pages to a page blob.
+
+ :param bytes page:
+ Content of the page.
+ :param int offset:
+ Start of byte range to use for writing to a section of the blob.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :param int length:
+ Number of bytes to use for writing to a section of the blob.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash of the page content. The storage
+ service checks the hash of the content that has arrived
+ with the hash that was sent. This is primarily valuable for detecting
+ bitflips on the wire if using http instead of https, as https (the default),
+ will already validate. Note that this MD5 hash is not stored with the
+ blob.
+ :keyword int if_sequence_number_lte:
+ If the blob's sequence number is less than or equal to
+ the specified value, the request proceeds; otherwise it fails.
+ :keyword int if_sequence_number_lt:
+ If the blob's sequence number is less than the specified
+ value, the request proceeds; otherwise it fails.
+ :keyword int if_sequence_number_eq:
+ If the blob's sequence number is equal to the specified
+ value, the request proceeds; otherwise it fails.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword str encoding:
+ Defaults to UTF-8.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified).
+ :rtype: dict(str, Any)
+ """
+ options = self._upload_page_options(
+ page=page,
+ offset=offset,
+ length=length,
+ **kwargs)
+ try:
+ return self._client.page_blob.upload_pages(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _upload_pages_from_url_options( # type: ignore
+ self, source_url, # type: str
+ offset, # type: int
+ length, # type: int
+ source_offset, # type: int
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+
+ # TODO: extract the code to a method format_range
+ if offset is None or offset % 512 != 0:
+ raise ValueError("offset must be an integer that aligns with 512 page size")
+ if length is None or length % 512 != 0:
+ raise ValueError("length must be an integer that aligns with 512 page size")
+ if source_offset is None or offset % 512 != 0:
+ raise ValueError("source_offset must be an integer that aligns with 512 page size")
+
+ # Format range
+ end_range = offset + length - 1
+ destination_range = 'bytes={0}-{1}'.format(offset, end_range)
+ source_range = 'bytes={0}-{1}'.format(source_offset, source_offset + length - 1) # should subtract 1 here?
+
+ seq_conditions = SequenceNumberAccessConditions(
+ if_sequence_number_less_than_or_equal_to=kwargs.pop('if_sequence_number_lte', None),
+ if_sequence_number_less_than=kwargs.pop('if_sequence_number_lt', None),
+ if_sequence_number_equal_to=kwargs.pop('if_sequence_number_eq', None)
+ )
+ source_authorization = kwargs.pop('source_authorization', None)
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ source_mod_conditions = get_source_conditions(kwargs)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ source_content_md5 = kwargs.pop('source_content_md5', None)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ options = {
+ 'copy_source_authorization': source_authorization,
+ 'source_url': source_url,
+ 'content_length': 0,
+ 'source_range': source_range,
+ 'range': destination_range,
+ 'source_content_md5': bytearray(source_content_md5) if source_content_md5 else None,
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'sequence_number_access_conditions': seq_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'source_modified_access_conditions': source_mod_conditions,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def upload_pages_from_url(self, source_url, # type: str
+ offset, # type: int
+ length, # type: int
+ source_offset, # type: int
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ """
+ The Upload Pages operation writes a range of pages to a page blob where
+ the contents are read from a URL.
+
+ :param str source_url:
+ The URL of the source data. It can point to any Azure Blob or File, that is either public or has a
+ shared access signature attached.
+ :param int offset:
+ Start of byte range to use for writing to a section of the blob.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :param int length:
+ Number of bytes to use for writing to a section of the blob.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :param int source_offset:
+ This indicates the start of the range of bytes(inclusive) that has to be taken from the copy source.
+ The service will read the same number of bytes as the destination range (length-offset).
+ :keyword bytes source_content_md5:
+ If given, the service will calculate the MD5 hash of the block content and compare against this value.
+ :keyword ~datetime.datetime source_if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the source resource has been modified since the specified time.
+ :keyword ~datetime.datetime source_if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the source resource has not been modified since the specified date/time.
+ :keyword str source_etag:
+ The source ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions source_match_condition:
+ The source match condition to use upon the etag.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int if_sequence_number_lte:
+ If the blob's sequence number is less than or equal to
+ the specified value, the request proceeds; otherwise it fails.
+ :keyword int if_sequence_number_lt:
+ If the blob's sequence number is less than the specified
+ value, the request proceeds; otherwise it fails.
+ :keyword int if_sequence_number_eq:
+ If the blob's sequence number is equal to the specified
+ value, the request proceeds; otherwise it fails.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ The destination ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The destination match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :keyword str source_authorization:
+ Authenticate as a service principal using a client secret to access a source blob. Ensure "bearer " is
+ the prefix of the source_authorization string.
+ """
+ options = self._upload_pages_from_url_options(
+ source_url=self._encode_source_url(source_url),
+ offset=offset,
+ length=length,
+ source_offset=source_offset,
+ **kwargs
+ )
+ try:
+ return self._client.page_blob.upload_pages_from_url(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _clear_page_options(self, offset, length, **kwargs):
+ # type: (int, int, **Any) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ seq_conditions = SequenceNumberAccessConditions(
+ if_sequence_number_less_than_or_equal_to=kwargs.pop('if_sequence_number_lte', None),
+ if_sequence_number_less_than=kwargs.pop('if_sequence_number_lt', None),
+ if_sequence_number_equal_to=kwargs.pop('if_sequence_number_eq', None)
+ )
+ mod_conditions = get_modify_conditions(kwargs)
+ if offset is None or offset % 512 != 0:
+ raise ValueError("offset must be an integer that aligns with 512 page size")
+ if length is None or length % 512 != 0:
+ raise ValueError("length must be an integer that aligns with 512 page size")
+ end_range = length + offset - 1 # Reformat to an inclusive range index
+ content_range = 'bytes={0}-{1}'.format(offset, end_range)
+
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ options = {
+ 'content_length': 0,
+ 'timeout': kwargs.pop('timeout', None),
+ 'range': content_range,
+ 'lease_access_conditions': access_conditions,
+ 'sequence_number_access_conditions': seq_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def clear_page(self, offset, length, **kwargs):
+ # type: (int, int, **Any) -> Dict[str, Union[str, datetime]]
+ """Clears a range of pages.
+
+ :param int offset:
+ Start of byte range to use for writing to a section of the blob.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :param int length:
+ Number of bytes to use for writing to a section of the blob.
+ Pages must be aligned with 512-byte boundaries, the start offset
+ must be a modulus of 512 and the length must be a modulus of
+ 512.
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int if_sequence_number_lte:
+ If the blob's sequence number is less than or equal to
+ the specified value, the request proceeds; otherwise it fails.
+ :keyword int if_sequence_number_lt:
+ If the blob's sequence number is less than the specified
+ value, the request proceeds; otherwise it fails.
+ :keyword int if_sequence_number_eq:
+ If the blob's sequence number is equal to the specified
+ value, the request proceeds; otherwise it fails.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag and last modified).
+ :rtype: dict(str, Any)
+ """
+ options = self._clear_page_options(offset, length, **kwargs)
+ try:
+ return self._client.page_blob.clear_pages(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _append_block_options( # type: ignore
+ self, data, # type: Union[AnyStr, Iterable[AnyStr], IO[AnyStr]]
+ length=None, # type: Optional[int]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+
+ if isinstance(data, six.text_type):
+ data = data.encode(kwargs.pop('encoding', 'UTF-8')) # type: ignore
+ if length is None:
+ length = get_length(data)
+ if length is None:
+ length, data = read_length(data)
+ if length == 0:
+ return {}
+ if isinstance(data, bytes):
+ data = data[:length]
+
+ appendpos_condition = kwargs.pop('appendpos_condition', None)
+ maxsize_condition = kwargs.pop('maxsize_condition', None)
+ validate_content = kwargs.pop('validate_content', False)
+ append_conditions = None
+ if maxsize_condition or appendpos_condition is not None:
+ append_conditions = AppendPositionAccessConditions(
+ max_size=maxsize_condition,
+ append_position=appendpos_condition
+ )
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+ options = {
+ 'body': data,
+ 'content_length': length,
+ 'timeout': kwargs.pop('timeout', None),
+ 'transactional_content_md5': None,
+ 'lease_access_conditions': access_conditions,
+ 'append_position_access_conditions': append_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'validate_content': validate_content,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def append_block( # type: ignore
+ self, data, # type: Union[AnyStr, Iterable[AnyStr], IO[AnyStr]]
+ length=None, # type: Optional[int]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Union[str, datetime, int]]
+ """Commits a new block of data to the end of the existing append blob.
+
+ :param data:
+ Content of the block. This can be bytes, text, an iterable or a file-like object.
+ :type data: bytes or str or Iterable
+ :param int length:
+ Size of the block in bytes.
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash of the block content. The storage
+ service checks the hash of the content that has arrived
+ with the hash that was sent. This is primarily valuable for detecting
+ bitflips on the wire if using http instead of https, as https (the default),
+ will already validate. Note that this MD5 hash is not stored with the
+ blob.
+ :keyword int maxsize_condition:
+ Optional conditional header. The max length in bytes permitted for
+ the append blob. If the Append Block operation would cause the blob
+ to exceed that limit or if the blob size is already greater than the
+ value specified in this header, the request will fail with
+ MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed).
+ :keyword int appendpos_condition:
+ Optional conditional header, used only for the Append Block operation.
+ A number indicating the byte offset to compare. Append Block will
+ succeed only if the append position is equal to this number. If it
+ is not, the request will fail with the AppendPositionConditionNotMet error
+ (HTTP status code 412 - Precondition Failed).
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword str encoding:
+ Defaults to UTF-8.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag, last modified, append offset, committed block count).
+ :rtype: dict(str, Any)
+ """
+ options = self._append_block_options(
+ data,
+ length=length,
+ **kwargs
+ )
+ try:
+ return self._client.append_blob.append_block(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _append_block_from_url_options( # type: ignore
+ self, copy_source_url, # type: str
+ source_offset=None, # type: Optional[int]
+ source_length=None, # type: Optional[int]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+
+ # If end range is provided, start range must be provided
+ if source_length is not None and source_offset is None:
+ raise ValueError("source_offset should also be specified if source_length is specified")
+ # Format based on whether length is present
+ source_range = None
+ if source_length is not None:
+ end_range = source_offset + source_length - 1
+ source_range = 'bytes={0}-{1}'.format(source_offset, end_range)
+ elif source_offset is not None:
+ source_range = "bytes={0}-".format(source_offset)
+
+ appendpos_condition = kwargs.pop('appendpos_condition', None)
+ maxsize_condition = kwargs.pop('maxsize_condition', None)
+ source_content_md5 = kwargs.pop('source_content_md5', None)
+ append_conditions = None
+ if maxsize_condition or appendpos_condition is not None:
+ append_conditions = AppendPositionAccessConditions(
+ max_size=maxsize_condition,
+ append_position=appendpos_condition
+ )
+ source_authorization = kwargs.pop('source_authorization', None)
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+ source_mod_conditions = get_source_conditions(kwargs)
+ cpk_scope_info = get_cpk_scope_info(kwargs)
+ cpk = kwargs.pop('cpk', None)
+ cpk_info = None
+ if cpk:
+ if self.scheme.lower() != 'https':
+ raise ValueError("Customer provided encryption key must be used over HTTPS.")
+ cpk_info = CpkInfo(encryption_key=cpk.key_value, encryption_key_sha256=cpk.key_hash,
+ encryption_algorithm=cpk.algorithm)
+
+ options = {
+ 'copy_source_authorization': source_authorization,
+ 'source_url': copy_source_url,
+ 'content_length': 0,
+ 'source_range': source_range,
+ 'source_content_md5': source_content_md5,
+ 'transactional_content_md5': None,
+ 'lease_access_conditions': access_conditions,
+ 'append_position_access_conditions': append_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'source_modified_access_conditions': source_mod_conditions,
+ 'cpk_scope_info': cpk_scope_info,
+ 'cpk_info': cpk_info,
+ 'cls': return_response_headers,
+ 'timeout': kwargs.pop('timeout', None)}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def append_block_from_url(self, copy_source_url, # type: str
+ source_offset=None, # type: Optional[int]
+ source_length=None, # type: Optional[int]
+ **kwargs):
+ # type: (...) -> Dict[str, Union[str, datetime, int]]
+ """
+ Creates a new block to be committed as part of a blob, where the contents are read from a source url.
+
+ :param str copy_source_url:
+ The URL of the source data. It can point to any Azure Blob or File, that is either public or has a
+ shared access signature attached.
+ :param int source_offset:
+ This indicates the start of the range of bytes (inclusive) that has to be taken from the copy source.
+ :param int source_length:
+ This indicates the end of the range of bytes that has to be taken from the copy source.
+ :keyword bytearray source_content_md5:
+ If given, the service will calculate the MD5 hash of the block content and compare against this value.
+ :keyword int maxsize_condition:
+ Optional conditional header. The max length in bytes permitted for
+ the append blob. If the Append Block operation would cause the blob
+ to exceed that limit or if the blob size is already greater than the
+ value specified in this header, the request will fail with
+ MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed).
+ :keyword int appendpos_condition:
+ Optional conditional header, used only for the Append Block operation.
+ A number indicating the byte offset to compare. Append Block will
+ succeed only if the append position is equal to this number. If it
+ is not, the request will fail with the
+ AppendPositionConditionNotMet error
+ (HTTP status code 412 - Precondition Failed).
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ The destination ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The destination match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~datetime.datetime source_if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the source resource has been modified since the specified time.
+ :keyword ~datetime.datetime source_if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the source resource has not been modified since the specified date/time.
+ :keyword str source_etag:
+ The source ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions source_match_condition:
+ The source match condition to use upon the etag.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :keyword str source_authorization:
+ Authenticate as a service principal using a client secret to access a source blob. Ensure "bearer " is
+ the prefix of the source_authorization string.
+ """
+ options = self._append_block_from_url_options(
+ copy_source_url=self._encode_source_url(copy_source_url),
+ source_offset=source_offset,
+ source_length=source_length,
+ **kwargs
+ )
+ try:
+ return self._client.append_blob.append_block_from_url(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _seal_append_blob_options(self, **kwargs):
+ # type: (...) -> Dict[str, Any]
+ if self.require_encryption or (self.key_encryption_key is not None):
+ raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
+
+ appendpos_condition = kwargs.pop('appendpos_condition', None)
+ append_conditions = None
+ if appendpos_condition is not None:
+ append_conditions = AppendPositionAccessConditions(
+ append_position=appendpos_condition
+ )
+ access_conditions = get_access_conditions(kwargs.pop('lease', None))
+ mod_conditions = get_modify_conditions(kwargs)
+
+ options = {
+ 'timeout': kwargs.pop('timeout', None),
+ 'lease_access_conditions': access_conditions,
+ 'append_position_access_conditions': append_conditions,
+ 'modified_access_conditions': mod_conditions,
+ 'cls': return_response_headers}
+ options.update(kwargs)
+ return options
+
+ @distributed_trace
+ def seal_append_blob(self, **kwargs):
+ # type: (...) -> Dict[str, Union[str, datetime, int]]
+ """The Seal operation seals the Append Blob to make it read-only.
+
+ .. versionadded:: 12.4.0
+
+ :keyword int appendpos_condition:
+ Optional conditional header, used only for the Append Block operation.
+ A number indicating the byte offset to compare. Append Block will
+ succeed only if the append position is equal to this number. If it
+ is not, the request will fail with the AppendPositionConditionNotMet error
+ (HTTP status code 412 - Precondition Failed).
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Blob-updated property dict (Etag, last modified, append offset, committed block count).
+ :rtype: dict(str, Any)
+ """
+ options = self._seal_append_blob_options(**kwargs)
+ try:
+ return self._client.append_blob.seal(**options) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def _get_container_client(self): # pylint: disable=client-method-missing-kwargs
+ # type: (...) -> ContainerClient
+ """Get a client to interact with the blob's parent container.
+
+ The container need not already exist. Defaults to current blob's credentials.
+
+ :returns: A ContainerClient.
+ :rtype: ~azure.storage.blob.ContainerClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START get_container_client_from_blob_client]
+ :end-before: [END get_container_client_from_blob_client]
+ :language: python
+ :dedent: 8
+ :caption: Get container client from blob object.
+ """
+ from ._container_client import ContainerClient
+ if not isinstance(self._pipeline._transport, TransportWrapper): # pylint: disable = protected-access
+ _pipeline = Pipeline(
+ transport=TransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
+ policies=self._pipeline._impl_policies # pylint: disable = protected-access
+ )
+ else:
+ _pipeline = self._pipeline # pylint: disable = protected-access
+ return ContainerClient(
+ "{}://{}".format(self.scheme, self.primary_hostname), container_name=self.container_name,
+ credential=self._raw_credential, api_version=self.api_version, _configuration=self._config,
+ _pipeline=_pipeline, _location_mode=self._location_mode, _hosts=self._hosts,
+ require_encryption=self.require_encryption, key_encryption_key=self.key_encryption_key,
+ key_resolver_function=self.key_resolver_function)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_blob_service_client.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_blob_service_client.py
new file mode 100644
index 00000000000..6740dc36062
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_blob_service_client.py
@@ -0,0 +1,740 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import functools
+import warnings
+from typing import ( # pylint: disable=unused-import
+ Union, Optional, Any, Iterable, Dict, List,
+ TYPE_CHECKING,
+ TypeVar)
+
+
+try:
+ from urllib.parse import urlparse
+except ImportError:
+ from urlparse import urlparse # type: ignore
+
+from azure.core.paging import ItemPaged
+from azure.core.exceptions import HttpResponseError
+from azure.core.pipeline import Pipeline
+from azure.core.tracing.decorator import distributed_trace
+
+from ._shared.models import LocationMode
+from ._shared.base_client import StorageAccountHostsMixin, TransportWrapper, parse_connection_str, parse_query
+from ._shared.parser import _to_utc_datetime
+from ._shared.response_handlers import return_response_headers, process_storage_error, \
+ parse_to_internal_user_delegation_key
+from ._generated import AzureBlobStorage
+from ._generated.models import StorageServiceProperties, KeyInfo
+from ._container_client import ContainerClient
+from ._blob_client import BlobClient
+from ._models import ContainerPropertiesPaged
+from ._list_blobs_helper import FilteredBlobPaged
+from ._serialize import get_api_version
+from ._deserialize import service_stats_deserialize, service_properties_deserialize
+
+if TYPE_CHECKING:
+ from datetime import datetime
+ from ._shared.models import UserDelegationKey
+ from ._lease import BlobLeaseClient
+ from ._models import (
+ ContainerProperties,
+ BlobProperties,
+ PublicAccess,
+ BlobAnalyticsLogging,
+ Metrics,
+ CorsRule,
+ RetentionPolicy,
+ StaticWebsite,
+ FilteredBlob
+ )
+
+ClassType = TypeVar("ClassType")
+
+
+class BlobServiceClient(StorageAccountHostsMixin):
+ """A client to interact with the Blob Service at the account level.
+
+ This client provides operations to retrieve and configure the account properties
+ as well as list, create and delete containers within the account.
+ For operations relating to a specific container or blob, clients for those entities
+ can also be retrieved using the `get_client` functions.
+
+ For more optional configuration, please click
+ `here `_.
+
+ :param str account_url:
+ The URL to the blob storage account. Any other entities included
+ in the URL path (e.g. container or blob) will be discarded. This URL can be optionally
+ authenticated with a SAS token.
+ :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.
+ 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.
+ :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.
+
+ .. versionadded:: 12.2.0
+
+ :keyword str secondary_hostname:
+ The hostname of the secondary endpoint.
+ :keyword int max_block_size: The maximum chunk size for uploading a block blob in chunks.
+ Defaults to 4*1024*1024, or 4MB.
+ :keyword int max_single_put_size: If the blob size is less than or equal max_single_put_size, then the blob will be
+ uploaded with only one http PUT request. If the blob size is larger than max_single_put_size,
+ the blob will be uploaded in chunks. Defaults to 64*1024*1024, or 64MB.
+ :keyword int min_large_block_upload_threshold: The minimum chunk size required to use the memory efficient
+ algorithm when uploading a block blob. Defaults to 4*1024*1024+1.
+ :keyword bool use_byte_buffer: Use a byte buffer for block blob uploads. Defaults to False.
+ :keyword int max_page_size: The maximum chunk size for uploading a page blob. Defaults to 4*1024*1024, or 4MB.
+ :keyword int max_single_get_size: The maximum size for a blob to be downloaded in a single call,
+ the exceeded part will be downloaded in chunks (could be parallel). Defaults to 32*1024*1024, or 32MB.
+ :keyword int max_chunk_get_size: The maximum chunk size used for downloading a blob. Defaults to 4*1024*1024,
+ or 4MB.
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_authentication.py
+ :start-after: [START create_blob_service_client]
+ :end-before: [END create_blob_service_client]
+ :language: python
+ :dedent: 8
+ :caption: Creating the BlobServiceClient with account url and credential.
+
+ .. literalinclude:: ../samples/blob_samples_authentication.py
+ :start-after: [START create_blob_service_client_oauth]
+ :end-before: [END create_blob_service_client_oauth]
+ :language: python
+ :dedent: 8
+ :caption: Creating the BlobServiceClient with Azure Identity credentials.
+ """
+
+ def __init__(
+ self, account_url, # type: str
+ credential=None, # type: Optional[Any]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ try:
+ if not account_url.lower().startswith('http'):
+ account_url = "https://" + account_url
+ except AttributeError:
+ raise ValueError("Account URL must be a string.")
+ parsed_url = urlparse(account_url.rstrip('/'))
+ if not parsed_url.netloc:
+ raise ValueError("Invalid URL: {}".format(account_url))
+
+ _, sas_token = parse_query(parsed_url.query)
+ self._query_str, credential = self._format_query_string(sas_token, credential)
+ super(BlobServiceClient, self).__init__(parsed_url, service='blob', credential=credential, **kwargs)
+ self._client = AzureBlobStorage(self.url, pipeline=self._pipeline)
+ self._client._config.version = get_api_version(kwargs) # pylint: disable=protected-access
+
+ def _format_url(self, hostname):
+ """Format the endpoint URL according to the current location
+ mode hostname.
+ """
+ return "{}://{}/{}".format(self.scheme, hostname, self._query_str)
+
+ @classmethod
+ def from_connection_string(
+ cls, # type: Type[ClassType]
+ conn_str, # type: str
+ credential=None, # type: Optional[Any]
+ **kwargs # type: Any
+ ): # type: (...) -> ClassType
+ """Create BlobServiceClient from a Connection String.
+
+ :param str conn_str:
+ A connection string to an Azure Storage account.
+ :param credential:
+ 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.
+ Credentials provided here will take precedence over those in the connection string.
+ :returns: A Blob service client.
+ :rtype: ~azure.storage.blob.BlobServiceClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_authentication.py
+ :start-after: [START auth_from_connection_string]
+ :end-before: [END auth_from_connection_string]
+ :language: python
+ :dedent: 8
+ :caption: Creating the BlobServiceClient from a connection string.
+ """
+ account_url, secondary, credential = parse_connection_str(conn_str, credential, 'blob')
+ if 'secondary_hostname' not in kwargs:
+ kwargs['secondary_hostname'] = secondary
+ return cls(account_url, credential=credential, **kwargs)
+
+ @distributed_trace
+ def get_user_delegation_key(self, key_start_time, # type: datetime
+ key_expiry_time, # type: datetime
+ **kwargs # type: Any
+ ):
+ # type: (...) -> UserDelegationKey
+ """
+ Obtain a user delegation key for the purpose of signing SAS tokens.
+ A token credential must be present on the service object for this request to succeed.
+
+ :param ~datetime.datetime key_start_time:
+ A DateTime value. Indicates when the key becomes valid.
+ :param ~datetime.datetime key_expiry_time:
+ A DateTime value. Indicates when the key stops being valid.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :return: The user delegation key.
+ :rtype: ~azure.storage.blob.UserDelegationKey
+ """
+ key_info = KeyInfo(start=_to_utc_datetime(key_start_time), expiry=_to_utc_datetime(key_expiry_time))
+ timeout = kwargs.pop('timeout', None)
+ try:
+ user_delegation_key = self._client.service.get_user_delegation_key(key_info=key_info,
+ timeout=timeout,
+ **kwargs) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ return parse_to_internal_user_delegation_key(user_delegation_key) # type: ignore
+
+ @distributed_trace
+ def get_account_information(self, **kwargs):
+ # type: (Any) -> Dict[str, str]
+ """Gets information related to the storage account.
+
+ The information can also be retrieved if the user has a SAS to a container or blob.
+ The keys in the returned dictionary include 'sku_name' and 'account_kind'.
+
+ :returns: A dict of account information (SKU and account type).
+ :rtype: dict(str, str)
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START get_blob_service_account_info]
+ :end-before: [END get_blob_service_account_info]
+ :language: python
+ :dedent: 8
+ :caption: Getting account information for the blob service.
+ """
+ try:
+ return self._client.service.get_account_info(cls=return_response_headers, **kwargs) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def get_service_stats(self, **kwargs):
+ # type: (**Any) -> Dict[str, Any]
+ """Retrieves statistics related to replication for the Blob service.
+
+ It is only available when read-access geo-redundant replication is enabled for
+ the storage account.
+
+ With geo-redundant replication, Azure Storage maintains your data durable
+ in two locations. In both locations, Azure Storage constantly maintains
+ multiple healthy replicas of your data. The location where you read,
+ create, update, or delete data is the primary storage account location.
+ The primary location exists in the region you choose at the time you
+ create an account via the Azure Management Azure classic portal, for
+ example, North Central US. The location to which your data is replicated
+ is the secondary location. The secondary location is automatically
+ determined based on the location of the primary; it is in a second data
+ center that resides in the same region as the primary location. Read-only
+ access is available from the secondary location, if read-access geo-redundant
+ replication is enabled for your storage account.
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :return: The blob service stats.
+ :rtype: Dict[str, Any]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START get_blob_service_stats]
+ :end-before: [END get_blob_service_stats]
+ :language: python
+ :dedent: 8
+ :caption: Getting service stats for the blob service.
+ """
+ timeout = kwargs.pop('timeout', None)
+ try:
+ stats = self._client.service.get_statistics( # type: ignore
+ timeout=timeout, use_location=LocationMode.SECONDARY, **kwargs)
+ return service_stats_deserialize(stats)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def get_service_properties(self, **kwargs):
+ # type: (Any) -> Dict[str, Any]
+ """Gets the properties of a storage account's Blob service, including
+ Azure Storage Analytics.
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: An object containing blob service properties such as
+ analytics logging, hour/minute metrics, cors rules, etc.
+ :rtype: Dict[str, Any]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START get_blob_service_properties]
+ :end-before: [END get_blob_service_properties]
+ :language: python
+ :dedent: 8
+ :caption: Getting service properties for the blob service.
+ """
+ timeout = kwargs.pop('timeout', None)
+ try:
+ service_props = self._client.service.get_properties(timeout=timeout, **kwargs)
+ return service_properties_deserialize(service_props)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def set_service_properties(
+ self, analytics_logging=None, # type: Optional[BlobAnalyticsLogging]
+ hour_metrics=None, # type: Optional[Metrics]
+ minute_metrics=None, # type: Optional[Metrics]
+ cors=None, # type: Optional[List[CorsRule]]
+ target_version=None, # type: Optional[str]
+ delete_retention_policy=None, # type: Optional[RetentionPolicy]
+ static_website=None, # type: Optional[StaticWebsite]
+ **kwargs
+ ):
+ # type: (...) -> None
+ """Sets the properties of a storage account's Blob service, including
+ Azure Storage Analytics.
+
+ If an element (e.g. analytics_logging) is left as None, the
+ existing settings on the service for that functionality are preserved.
+
+ :param analytics_logging:
+ Groups the Azure Analytics Logging settings.
+ :type analytics_logging: ~azure.storage.blob.BlobAnalyticsLogging
+ :param hour_metrics:
+ The hour metrics settings provide a summary of request
+ statistics grouped by API in hourly aggregates for blobs.
+ :type hour_metrics: ~azure.storage.blob.Metrics
+ :param minute_metrics:
+ The minute metrics settings provide request statistics
+ for each minute for blobs.
+ :type minute_metrics: ~azure.storage.blob.Metrics
+ :param cors:
+ You can include up to five CorsRule elements in the
+ list. If an empty list is specified, all CORS rules will be deleted,
+ and CORS will be disabled for the service.
+ :type cors: list[~azure.storage.blob.CorsRule]
+ :param str target_version:
+ Indicates the default version to use for requests if an incoming
+ request's version is not specified.
+ :param delete_retention_policy:
+ The delete retention policy specifies whether to retain deleted blobs.
+ It also specifies the number of days and versions of blob to keep.
+ :type delete_retention_policy: ~azure.storage.blob.RetentionPolicy
+ :param static_website:
+ Specifies whether the static website feature is enabled,
+ and if yes, indicates the index document and 404 error document to use.
+ :type static_website: ~azure.storage.blob.StaticWebsite
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: None
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START set_blob_service_properties]
+ :end-before: [END set_blob_service_properties]
+ :language: python
+ :dedent: 8
+ :caption: Setting service properties for the blob service.
+ """
+ if all(parameter is None for parameter in [
+ analytics_logging, hour_metrics, minute_metrics, cors,
+ target_version, delete_retention_policy, static_website]):
+ raise ValueError("set_service_properties should be called with at least one parameter")
+
+ props = StorageServiceProperties(
+ logging=analytics_logging,
+ hour_metrics=hour_metrics,
+ minute_metrics=minute_metrics,
+ cors=cors,
+ default_service_version=target_version,
+ delete_retention_policy=delete_retention_policy,
+ static_website=static_website
+ )
+ timeout = kwargs.pop('timeout', None)
+ try:
+ self._client.service.set_properties(props, timeout=timeout, **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def list_containers(
+ self, name_starts_with=None, # type: Optional[str]
+ include_metadata=False, # type: Optional[bool]
+ **kwargs
+ ):
+ # type: (...) -> ItemPaged[ContainerProperties]
+ """Returns a generator to list the containers under the specified account.
+
+ The generator will lazily follow the continuation tokens returned by
+ the service and stop when all containers have been returned.
+
+ :param str name_starts_with:
+ Filters the results to return only containers whose names
+ begin with the specified prefix.
+ :param bool include_metadata:
+ Specifies that container metadata to be returned in the response.
+ The default value is `False`.
+ :keyword bool include_deleted:
+ Specifies that deleted containers to be returned in the response. This is for container restore enabled
+ account. The default value is `False`.
+ .. versionadded:: 12.4.0
+ :keyword bool include_system:
+ Flag specifying that system containers should be included.
+ .. versionadded:: 12.10.0
+ :keyword int results_per_page:
+ The maximum number of container names to retrieve per API
+ call. If the request does not specify the server will return up to 5,000 items.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: An iterable (auto-paging) of ContainerProperties.
+ :rtype: ~azure.core.paging.ItemPaged[~azure.storage.blob.ContainerProperties]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START bsc_list_containers]
+ :end-before: [END bsc_list_containers]
+ :language: python
+ :dedent: 12
+ :caption: Listing the containers in the blob service.
+ """
+ include = ['metadata'] if include_metadata else []
+ include_deleted = kwargs.pop('include_deleted', None)
+ if include_deleted:
+ include.append("deleted")
+ include_system = kwargs.pop('include_system', None)
+ if include_system:
+ include.append("system")
+
+ timeout = kwargs.pop('timeout', None)
+ results_per_page = kwargs.pop('results_per_page', None)
+ command = functools.partial(
+ self._client.service.list_containers_segment,
+ prefix=name_starts_with,
+ include=include,
+ timeout=timeout,
+ **kwargs)
+ return ItemPaged(
+ command,
+ prefix=name_starts_with,
+ results_per_page=results_per_page,
+ page_iterator_class=ContainerPropertiesPaged
+ )
+
+ @distributed_trace
+ def find_blobs_by_tags(self, filter_expression, **kwargs):
+ # type: (str, **Any) -> ItemPaged[FilteredBlob]
+ """The Filter Blobs operation enables callers to list blobs across all
+ containers whose tags match a given search expression. Filter blobs
+ searches across all containers within a storage account but can be
+ scoped within the expression to a single container.
+
+ :param str filter_expression:
+ The expression to find blobs whose tags matches the specified condition.
+ eg. "\"yourtagname\"='firsttag' and \"yourtagname2\"='secondtag'"
+ To specify a container, eg. "@container='containerName' and \"Name\"='C'"
+ :keyword int results_per_page:
+ The max result per page when paginating.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: An iterable (auto-paging) response of BlobProperties.
+ :rtype: ~azure.core.paging.ItemPaged[~azure.storage.blob.FilteredBlob]
+ """
+
+ results_per_page = kwargs.pop('results_per_page', None)
+ timeout = kwargs.pop('timeout', None)
+ command = functools.partial(
+ self._client.service.filter_blobs,
+ where=filter_expression,
+ timeout=timeout,
+ **kwargs)
+ return ItemPaged(
+ command, results_per_page=results_per_page,
+ page_iterator_class=FilteredBlobPaged)
+
+ @distributed_trace
+ def create_container(
+ self, name, # type: str
+ metadata=None, # type: Optional[Dict[str, str]]
+ public_access=None, # type: Optional[Union[PublicAccess, str]]
+ **kwargs
+ ):
+ # type: (...) -> ContainerClient
+ """Creates a new container under the specified account.
+
+ If the container with the same name already exists, a ResourceExistsError will
+ be raised. This method returns a client with which to interact with the newly
+ created container.
+
+ :param str name: The name of the container to create.
+ :param metadata:
+ A dict with name-value pairs to associate with the
+ container as metadata. Example: `{'Category':'test'}`
+ :type metadata: dict(str, str)
+ :param public_access:
+ Possible values include: 'container', 'blob'.
+ :type public_access: str or ~azure.storage.blob.PublicAccess
+ :keyword container_encryption_scope:
+ Specifies the default encryption scope to set on the container and use for
+ all future writes.
+
+ .. versionadded:: 12.2.0
+
+ :paramtype container_encryption_scope: dict or ~azure.storage.blob.ContainerEncryptionScope
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: ~azure.storage.blob.ContainerClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START bsc_create_container]
+ :end-before: [END bsc_create_container]
+ :language: python
+ :dedent: 12
+ :caption: Creating a container in the blob service.
+ """
+ container = self.get_container_client(name)
+ kwargs.setdefault('merge_span', True)
+ timeout = kwargs.pop('timeout', None)
+ container.create_container(
+ metadata=metadata, public_access=public_access, timeout=timeout, **kwargs)
+ return container
+
+ @distributed_trace
+ def delete_container(
+ self, container, # type: Union[ContainerProperties, str]
+ lease=None, # type: Optional[Union[BlobLeaseClient, str]]
+ **kwargs
+ ):
+ # type: (...) -> None
+ """Marks the specified container for deletion.
+
+ The container and any blobs contained within it are later deleted during garbage collection.
+ If the container is not found, a ResourceNotFoundError will be raised.
+
+ :param container:
+ The container to delete. This can either be the name of the container,
+ or an instance of ContainerProperties.
+ :type container: str or ~azure.storage.blob.ContainerProperties
+ :param lease:
+ If specified, delete_container only succeeds if the
+ container's lease is active and matches this ID.
+ Required if the container has an active lease.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: None
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START bsc_delete_container]
+ :end-before: [END bsc_delete_container]
+ :language: python
+ :dedent: 12
+ :caption: Deleting a container in the blob service.
+ """
+ container = self.get_container_client(container) # type: ignore
+ kwargs.setdefault('merge_span', True)
+ timeout = kwargs.pop('timeout', None)
+ container.delete_container( # type: ignore
+ lease=lease,
+ timeout=timeout,
+ **kwargs)
+
+ @distributed_trace
+ def _rename_container(self, name, new_name, **kwargs):
+ # type: (str, str, **Any) -> ContainerClient
+ """Renames a container.
+
+ Operation is successful only if the source container exists.
+
+ :param str name:
+ The name of the container to rename.
+ :param str new_name:
+ The new container name the user wants to rename to.
+ :keyword lease:
+ Specify this to perform only if the lease ID given
+ matches the active lease ID of the source container.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: ~azure.storage.blob.ContainerClient
+ """
+ renamed_container = self.get_container_client(new_name)
+ lease = kwargs.pop('lease', None)
+ try:
+ kwargs['source_lease_id'] = lease.id # type: str
+ except AttributeError:
+ kwargs['source_lease_id'] = lease
+ try:
+ renamed_container._client.container.rename(name, **kwargs) # pylint: disable = protected-access
+ return renamed_container
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def undelete_container(self, deleted_container_name, deleted_container_version, **kwargs):
+ # type: (str, str, **Any) -> ContainerClient
+ """Restores soft-deleted container.
+
+ Operation will only be successful if used within the specified number of days
+ set in the delete retention policy.
+
+ .. versionadded:: 12.4.0
+ This operation was introduced in API version '2019-12-12'.
+
+ :param str deleted_container_name:
+ Specifies the name of the deleted container to restore.
+ :param str deleted_container_version:
+ Specifies the version of the deleted container to restore.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: ~azure.storage.blob.ContainerClient
+ """
+ new_name = kwargs.pop('new_name', None)
+ if new_name:
+ warnings.warn("`new_name` is no longer supported.", DeprecationWarning)
+ container = self.get_container_client(new_name or deleted_container_name)
+ try:
+ container._client.container.restore(deleted_container_name=deleted_container_name, # pylint: disable = protected-access
+ deleted_container_version=deleted_container_version,
+ timeout=kwargs.pop('timeout', None), **kwargs)
+ return container
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def get_container_client(self, container):
+ # type: (Union[ContainerProperties, str]) -> ContainerClient
+ """Get a client to interact with the specified container.
+
+ The container need not already exist.
+
+ :param container:
+ The container. This can either be the name of the container,
+ or an instance of ContainerProperties.
+ :type container: str or ~azure.storage.blob.ContainerProperties
+ :returns: A ContainerClient.
+ :rtype: ~azure.storage.blob.ContainerClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START bsc_get_container_client]
+ :end-before: [END bsc_get_container_client]
+ :language: python
+ :dedent: 8
+ :caption: Getting the container client to interact with a specific container.
+ """
+ try:
+ container_name = container.name
+ except AttributeError:
+ container_name = container
+ _pipeline = Pipeline(
+ transport=TransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
+ policies=self._pipeline._impl_policies # pylint: disable = protected-access
+ )
+ return ContainerClient(
+ self.url, container_name=container_name,
+ credential=self.credential, api_version=self.api_version, _configuration=self._config,
+ _pipeline=_pipeline, _location_mode=self._location_mode, _hosts=self._hosts,
+ require_encryption=self.require_encryption, key_encryption_key=self.key_encryption_key,
+ key_resolver_function=self.key_resolver_function)
+
+ def get_blob_client(
+ self, container, # type: Union[ContainerProperties, str]
+ blob, # type: Union[BlobProperties, str]
+ snapshot=None # type: Optional[Union[Dict[str, Any], str]]
+ ):
+ # type: (...) -> BlobClient
+ """Get a client to interact with the specified blob.
+
+ The blob need not already exist.
+
+ :param container:
+ The container that the blob is in. This can either be the name of the container,
+ or an instance of ContainerProperties.
+ :type container: str or ~azure.storage.blob.ContainerProperties
+ :param blob:
+ The blob with which to interact. This can either be the name of the blob,
+ or an instance of BlobProperties.
+ :type blob: str or ~azure.storage.blob.BlobProperties
+ :param snapshot:
+ The optional blob snapshot on which to operate. This can either be the ID of the snapshot,
+ or a dictionary output returned by :func:`~azure.storage.blob.BlobClient.create_snapshot()`.
+ :type snapshot: str or dict(str, Any)
+ :returns: A BlobClient.
+ :rtype: ~azure.storage.blob.BlobClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START bsc_get_blob_client]
+ :end-before: [END bsc_get_blob_client]
+ :language: python
+ :dedent: 12
+ :caption: Getting the blob client to interact with a specific blob.
+ """
+ try:
+ container_name = container.name
+ except AttributeError:
+ container_name = container
+ try:
+ blob_name = blob.name
+ except AttributeError:
+ blob_name = blob
+ _pipeline = Pipeline(
+ transport=TransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
+ policies=self._pipeline._impl_policies # pylint: disable = protected-access
+ )
+ return BlobClient( # type: ignore
+ self.url, container_name=container_name, blob_name=blob_name, snapshot=snapshot,
+ credential=self.credential, api_version=self.api_version, _configuration=self._config,
+ _pipeline=_pipeline, _location_mode=self._location_mode, _hosts=self._hosts,
+ require_encryption=self.require_encryption, key_encryption_key=self.key_encryption_key,
+ key_resolver_function=self.key_resolver_function)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_container_client.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_container_client.py
new file mode 100644
index 00000000000..b5cbd58ba77
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_container_client.py
@@ -0,0 +1,1601 @@
+# pylint: disable=too-many-lines
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import functools
+from typing import ( # pylint: disable=unused-import
+ Union, Optional, Any, Iterable, AnyStr, Dict, List, Tuple, IO, Iterator,
+ TYPE_CHECKING,
+ TypeVar)
+
+
+try:
+ from urllib.parse import urlparse, quote, unquote
+except ImportError:
+ from urlparse import urlparse # type: ignore
+ from urllib2 import quote, unquote # type: ignore
+
+import six
+
+from azure.core import MatchConditions
+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
+from azure.core.pipeline.transport import HttpRequest
+
+from ._shared.base_client import StorageAccountHostsMixin, TransportWrapper, parse_connection_str, parse_query
+from ._shared.request_handlers import add_metadata_headers, serialize_iso
+from ._shared.response_handlers import (
+ process_storage_error,
+ return_response_headers,
+ return_headers_and_deserialized)
+from ._generated import AzureBlobStorage
+from ._generated.models import SignedIdentifier
+from ._deserialize import deserialize_container_properties
+from ._serialize import get_modify_conditions, get_container_cpk_scope_info, get_api_version, get_access_conditions
+from ._models import ( # pylint: disable=unused-import
+ ContainerProperties,
+ BlobProperties,
+ BlobType,
+ FilteredBlob)
+from ._list_blobs_helper import BlobPrefix, BlobPropertiesPaged, FilteredBlobPaged
+from ._lease import BlobLeaseClient
+from ._blob_client import BlobClient
+
+if TYPE_CHECKING:
+ from azure.core.pipeline.transport import HttpTransport, HttpResponse # pylint: disable=ungrouped-imports
+ from azure.core.pipeline.policies import HTTPPolicy # pylint: disable=ungrouped-imports
+ from datetime import datetime
+ from ._models import ( # pylint: disable=unused-import
+ PublicAccess,
+ AccessPolicy,
+ ContentSettings,
+ StandardBlobTier,
+ PremiumPageBlobTier)
+
+
+def _get_blob_name(blob):
+ """Return the blob name.
+
+ :param blob: A blob string or BlobProperties
+ :rtype: str
+ """
+ try:
+ return blob.get('name')
+ except AttributeError:
+ return blob
+
+
+ClassType = TypeVar("ClassType")
+
+
+class ContainerClient(StorageAccountHostsMixin): # pylint: disable=too-many-public-methods
+ """A client to interact with a specific container, although that container
+ may not yet exist.
+
+ For operations relating to a specific blob within this container, a blob client can be
+ retrieved using the :func:`~get_blob_client` function.
+
+ For more optional configuration, please click
+ `here `_.
+
+ :param str account_url:
+ The URI to the storage account. In order to create a client given the full URI to the container,
+ use the :func:`from_container_url` classmethod.
+ :param container_name:
+ The name of the container for the blob.
+ :type container_name: str
+ :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.
+ 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.
+ :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.
+
+ .. versionadded:: 12.2.0
+
+ :keyword str secondary_hostname:
+ The hostname of the secondary endpoint.
+ :keyword int max_block_size: The maximum chunk size for uploading a block blob in chunks.
+ Defaults to 4*1024*1024, or 4MB.
+ :keyword int max_single_put_size: If the blob size is less than or equal max_single_put_size, then the blob will be
+ uploaded with only one http PUT request. If the blob size is larger than max_single_put_size,
+ the blob will be uploaded in chunks. Defaults to 64*1024*1024, or 64MB.
+ :keyword int min_large_block_upload_threshold: The minimum chunk size required to use the memory efficient
+ algorithm when uploading a block blob. Defaults to 4*1024*1024+1.
+ :keyword bool use_byte_buffer: Use a byte buffer for block blob uploads. Defaults to False.
+ :keyword int max_page_size: The maximum chunk size for uploading a page blob. Defaults to 4*1024*1024, or 4MB.
+ :keyword int max_single_get_size: The maximum size for a blob to be downloaded in a single call,
+ the exceeded part will be downloaded in chunks (could be parallel). Defaults to 32*1024*1024, or 32MB.
+ :keyword int max_chunk_get_size: The maximum chunk size used for downloading a blob. Defaults to 4*1024*1024,
+ or 4MB.
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START create_container_client_from_service]
+ :end-before: [END create_container_client_from_service]
+ :language: python
+ :dedent: 8
+ :caption: Get a ContainerClient from an existing BlobServiceClient.
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START create_container_client_sasurl]
+ :end-before: [END create_container_client_sasurl]
+ :language: python
+ :dedent: 8
+ :caption: Creating the container client directly.
+ """
+ def __init__(
+ self, account_url, # type: str
+ container_name, # type: str
+ credential=None, # type: Optional[Any]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ try:
+ if not account_url.lower().startswith('http'):
+ account_url = "https://" + account_url
+ except AttributeError:
+ raise ValueError("Container URL must be a string.")
+ parsed_url = urlparse(account_url.rstrip('/'))
+ if not container_name:
+ raise ValueError("Please specify a container name.")
+ if not parsed_url.netloc:
+ raise ValueError("Invalid URL: {}".format(account_url))
+
+ _, sas_token = parse_query(parsed_url.query)
+ self.container_name = container_name
+ # This parameter is used for the hierarchy traversal. Give precedence to credential.
+ self._raw_credential = credential if credential else sas_token
+ self._query_str, credential = self._format_query_string(sas_token, credential)
+ super(ContainerClient, self).__init__(parsed_url, service='blob', credential=credential, **kwargs)
+ self._client = AzureBlobStorage(self.url, pipeline=self._pipeline)
+ self._client._config.version = get_api_version(kwargs) # pylint: disable=protected-access
+
+ def _format_url(self, hostname):
+ container_name = self.container_name
+ if isinstance(container_name, six.text_type):
+ container_name = container_name.encode('UTF-8')
+ return "{}://{}/{}{}".format(
+ self.scheme,
+ hostname,
+ quote(container_name),
+ self._query_str)
+
+ @classmethod
+ def from_container_url(cls, container_url, credential=None, **kwargs):
+ # type: (Type[ClassType], str, Optional[Any], Any) -> ClassType
+ """Create ContainerClient from a container url.
+
+ :param str container_url:
+ The full endpoint URL to the Container, including SAS token if used. This could be
+ either the primary endpoint, or the secondary endpoint depending on the current `location_mode`.
+ :type container_url: str
+ :param credential:
+ 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.
+ 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.
+ :returns: A container client.
+ :rtype: ~azure.storage.blob.ContainerClient
+ """
+ try:
+ if not container_url.lower().startswith('http'):
+ container_url = "https://" + container_url
+ except AttributeError:
+ raise ValueError("Container URL must be a string.")
+ parsed_url = urlparse(container_url.rstrip('/'))
+ if not parsed_url.netloc:
+ raise ValueError("Invalid URL: {}".format(container_url))
+
+ container_path = parsed_url.path.lstrip('/').split('/')
+ account_path = ""
+ if len(container_path) > 1:
+ account_path = "/" + "/".join(container_path[:-1])
+ account_url = "{}://{}{}?{}".format(
+ parsed_url.scheme,
+ parsed_url.netloc.rstrip('/'),
+ account_path,
+ parsed_url.query)
+ container_name = unquote(container_path[-1])
+ if not container_name:
+ raise ValueError("Invalid URL. Please provide a URL with a valid container name")
+ return cls(account_url, container_name=container_name, credential=credential, **kwargs)
+
+ @classmethod
+ def from_connection_string(
+ cls, # type: Type[ClassType]
+ conn_str, # type: str
+ container_name, # type: str
+ credential=None, # type: Optional[Any]
+ **kwargs # type: Any
+ ): # type: (...) -> ClassType
+ """Create ContainerClient from a Connection String.
+
+ :param str conn_str:
+ A connection string to an Azure Storage account.
+ :param container_name:
+ The container name for the blob.
+ :type container_name: str
+ :param credential:
+ 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.
+ Credentials provided here will take precedence over those in the connection string.
+ :returns: A container client.
+ :rtype: ~azure.storage.blob.ContainerClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_authentication.py
+ :start-after: [START auth_from_connection_string_container]
+ :end-before: [END auth_from_connection_string_container]
+ :language: python
+ :dedent: 8
+ :caption: Creating the ContainerClient from a connection string.
+ """
+ account_url, secondary, credential = parse_connection_str(conn_str, credential, 'blob')
+ if 'secondary_hostname' not in kwargs:
+ kwargs['secondary_hostname'] = secondary
+ return cls(
+ account_url, container_name=container_name, credential=credential, **kwargs)
+
+ @distributed_trace
+ def create_container(self, metadata=None, public_access=None, **kwargs):
+ # type: (Optional[Dict[str, str]], Optional[Union[PublicAccess, str]], **Any) -> None
+ """
+ Creates a new container under the specified account. If the container
+ with the same name already exists, the operation fails.
+
+ :param metadata:
+ A dict with name_value pairs to associate with the
+ container as metadata. Example:{'Category':'test'}
+ :type metadata: dict[str, str]
+ :param ~azure.storage.blob.PublicAccess public_access:
+ Possible values include: 'container', 'blob'.
+ :keyword container_encryption_scope:
+ Specifies the default encryption scope to set on the container and use for
+ all future writes.
+
+ .. versionadded:: 12.2.0
+
+ :paramtype container_encryption_scope: dict or ~azure.storage.blob.ContainerEncryptionScope
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: None
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START create_container]
+ :end-before: [END create_container]
+ :language: python
+ :dedent: 12
+ :caption: Creating a container to store blobs.
+ """
+ headers = kwargs.pop('headers', {})
+ timeout = kwargs.pop('timeout', None)
+ headers.update(add_metadata_headers(metadata)) # type: ignore
+ container_cpk_scope_info = get_container_cpk_scope_info(kwargs)
+ try:
+ return self._client.container.create( # type: ignore
+ timeout=timeout,
+ access=public_access,
+ container_cpk_scope_info=container_cpk_scope_info,
+ cls=return_response_headers,
+ headers=headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def _rename_container(self, new_name, **kwargs):
+ # type: (str, **Any) -> ContainerClient
+ """Renames a container.
+
+ Operation is successful only if the source container exists.
+
+ :param str new_name:
+ The new container name the user wants to rename to.
+ :keyword lease:
+ Specify this to perform only if the lease ID given
+ matches the active lease ID of the source container.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: ~azure.storage.blob.ContainerClient
+ """
+ lease = kwargs.pop('lease', None)
+ try:
+ kwargs['source_lease_id'] = lease.id # type: str
+ except AttributeError:
+ kwargs['source_lease_id'] = lease
+ try:
+ renamed_container = ContainerClient(
+ "{}://{}".format(self.scheme, self.primary_hostname), container_name=new_name,
+ credential=self.credential, api_version=self.api_version, _configuration=self._config,
+ _pipeline=self._pipeline, _location_mode=self._location_mode, _hosts=self._hosts,
+ require_encryption=self.require_encryption, key_encryption_key=self.key_encryption_key,
+ key_resolver_function=self.key_resolver_function)
+ renamed_container._client.container.rename(self.container_name, **kwargs) # pylint: disable = protected-access
+ return renamed_container
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def delete_container(
+ self, **kwargs):
+ # type: (Any) -> None
+ """
+ Marks the specified container for deletion. The container and any blobs
+ contained within it are later deleted during garbage collection.
+
+ :keyword lease:
+ If specified, delete_container only succeeds if the
+ container's lease is active and matches this ID.
+ Required if the container has an active lease.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: None
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START delete_container]
+ :end-before: [END delete_container]
+ :language: python
+ :dedent: 12
+ :caption: Delete a container.
+ """
+ lease = kwargs.pop('lease', None)
+ access_conditions = get_access_conditions(lease)
+ mod_conditions = get_modify_conditions(kwargs)
+ timeout = kwargs.pop('timeout', None)
+ try:
+ self._client.container.delete(
+ timeout=timeout,
+ lease_access_conditions=access_conditions,
+ modified_access_conditions=mod_conditions,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def acquire_lease(
+ self, lease_duration=-1, # type: int
+ lease_id=None, # type: Optional[str]
+ **kwargs):
+ # type: (...) -> BlobLeaseClient
+ """
+ Requests a new lease. If the container does not have an active lease,
+ the Blob service creates a lease on the container and returns a new
+ lease ID.
+
+ :param int lease_duration:
+ Specifies the duration of the lease, in seconds, or negative one
+ (-1) for a lease that never expires. A non-infinite lease can be
+ between 15 and 60 seconds. A lease duration cannot be changed
+ using renew or change. Default is -1 (infinite lease).
+ :param str lease_id:
+ Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: A BlobLeaseClient object, that can be run in a context manager.
+ :rtype: ~azure.storage.blob.BlobLeaseClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START acquire_lease_on_container]
+ :end-before: [END acquire_lease_on_container]
+ :language: python
+ :dedent: 8
+ :caption: Acquiring a lease on the container.
+ """
+ lease = BlobLeaseClient(self, lease_id=lease_id) # type: ignore
+ kwargs.setdefault('merge_span', True)
+ timeout = kwargs.pop('timeout', None)
+ lease.acquire(lease_duration=lease_duration, timeout=timeout, **kwargs)
+ return lease
+
+ @distributed_trace
+ def get_account_information(self, **kwargs):
+ # type: (**Any) -> Dict[str, str]
+ """Gets information related to the storage account.
+
+ The information can also be retrieved if the user has a SAS to a container or blob.
+ The keys in the returned dictionary include 'sku_name' and 'account_kind'.
+
+ :returns: A dict of account information (SKU and account type).
+ :rtype: dict(str, str)
+ """
+ try:
+ return self._client.container.get_account_info(cls=return_response_headers, **kwargs) # type: ignore
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def get_container_properties(self, **kwargs):
+ # type: (Any) -> ContainerProperties
+ """Returns all user-defined metadata and system properties for the specified
+ container. The data returned does not include the container's list of blobs.
+
+ :keyword lease:
+ If specified, get_container_properties only succeeds if the
+ container's lease is active and matches this ID.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :return: Properties for the specified container within a container object.
+ :rtype: ~azure.storage.blob.ContainerProperties
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START get_container_properties]
+ :end-before: [END get_container_properties]
+ :language: python
+ :dedent: 12
+ :caption: Getting properties on the container.
+ """
+ lease = kwargs.pop('lease', None)
+ access_conditions = get_access_conditions(lease)
+ timeout = kwargs.pop('timeout', None)
+ try:
+ response = self._client.container.get_properties(
+ timeout=timeout,
+ lease_access_conditions=access_conditions,
+ cls=deserialize_container_properties,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ 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]]
+ **kwargs
+ ):
+ # type: (...) -> Dict[str, Union[str, datetime]]
+ """Sets one or more user-defined name-value pairs for the specified
+ container. Each call to this operation replaces all existing metadata
+ attached to the container. To remove all metadata from the container,
+ call this operation with no metadata dict.
+
+ :param metadata:
+ A dict containing name-value pairs to associate with the container as
+ metadata. Example: {'category':'test'}
+ :type metadata: dict[str, str]
+ :keyword lease:
+ If specified, set_container_metadata only succeeds if the
+ container's lease is active and matches this ID.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Container-updated property dict (Etag and last modified).
+ :rtype: dict[str, str or datetime]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START set_container_metadata]
+ :end-before: [END set_container_metadata]
+ :language: python
+ :dedent: 12
+ :caption: Setting metadata on the container.
+ """
+ headers = kwargs.pop('headers', {})
+ headers.update(add_metadata_headers(metadata))
+ lease = kwargs.pop('lease', None)
+ access_conditions = get_access_conditions(lease)
+ mod_conditions = get_modify_conditions(kwargs)
+ timeout = kwargs.pop('timeout', None)
+ try:
+ return self._client.container.set_metadata( # type: ignore
+ timeout=timeout,
+ lease_access_conditions=access_conditions,
+ modified_access_conditions=mod_conditions,
+ cls=return_response_headers,
+ headers=headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def _get_blob_service_client(self): # pylint: disable=client-method-missing-kwargs
+ # type: (...) -> BlobServiceClient
+ """Get a client to interact with the container's parent service account.
+
+ Defaults to current container's credentials.
+
+ :returns: A BlobServiceClient.
+ :rtype: ~azure.storage.blob.BlobServiceClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_service.py
+ :start-after: [START get_blob_service_client_from_container_client]
+ :end-before: [END get_blob_service_client_from_container_client]
+ :language: python
+ :dedent: 8
+ :caption: Get blob service client from container object.
+ """
+ from ._blob_service_client import BlobServiceClient
+ if not isinstance(self._pipeline._transport, TransportWrapper): # pylint: disable = protected-access
+ _pipeline = Pipeline(
+ transport=TransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
+ policies=self._pipeline._impl_policies # pylint: disable = protected-access
+ )
+ else:
+ _pipeline = self._pipeline # pylint: disable = protected-access
+ return BlobServiceClient(
+ "{}://{}".format(self.scheme, self.primary_hostname),
+ credential=self._raw_credential, api_version=self.api_version, _configuration=self._config,
+ _location_mode=self._location_mode, _hosts=self._hosts, require_encryption=self.require_encryption,
+ key_encryption_key=self.key_encryption_key, key_resolver_function=self.key_resolver_function,
+ _pipeline=_pipeline)
+
+ @distributed_trace
+ def get_container_access_policy(self, **kwargs):
+ # type: (Any) -> Dict[str, Any]
+ """Gets the permissions for the specified container.
+ The permissions indicate whether container data may be accessed publicly.
+
+ :keyword lease:
+ If specified, get_container_access_policy only succeeds if the
+ container's lease is active and matches this ID.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Access policy information in a dict.
+ :rtype: dict[str, Any]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START get_container_access_policy]
+ :end-before: [END get_container_access_policy]
+ :language: python
+ :dedent: 12
+ :caption: Getting the access policy on the container.
+ """
+ lease = kwargs.pop('lease', None)
+ access_conditions = get_access_conditions(lease)
+ timeout = kwargs.pop('timeout', None)
+ try:
+ response, identifiers = self._client.container.get_access_policy(
+ timeout=timeout,
+ lease_access_conditions=access_conditions,
+ cls=return_headers_and_deserialized,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ return {
+ 'public_access': response.get('blob_public_access'),
+ 'signed_identifiers': identifiers or []
+ }
+
+ @distributed_trace
+ def set_container_access_policy(
+ self, signed_identifiers, # type: Dict[str, AccessPolicy]
+ public_access=None, # type: Optional[Union[str, PublicAccess]]
+ **kwargs
+ ): # type: (...) -> Dict[str, Union[str, datetime]]
+ """Sets the permissions for the specified container or stored access
+ policies that may be used with Shared Access Signatures. The permissions
+ indicate whether blobs in a container may be accessed publicly.
+
+ :param signed_identifiers:
+ A dictionary of access policies to associate with the container. The
+ dictionary may contain up to 5 elements. An empty dictionary
+ will clear the access policies set on the service.
+ :type signed_identifiers: dict[str, ~azure.storage.blob.AccessPolicy]
+ :param ~azure.storage.blob.PublicAccess public_access:
+ Possible values include: 'container', 'blob'.
+ :keyword lease:
+ Required if the container has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A datetime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified date/time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A datetime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: Container-updated property dict (Etag and last modified).
+ :rtype: dict[str, str or ~datetime.datetime]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START set_container_access_policy]
+ :end-before: [END set_container_access_policy]
+ :language: python
+ :dedent: 12
+ :caption: Setting access policy on the container.
+ """
+ if len(signed_identifiers) > 5:
+ raise ValueError(
+ 'Too many access policies provided. The server does not support setting '
+ 'more than 5 access policies on a single resource.')
+ identifiers = []
+ for key, value in signed_identifiers.items():
+ if value:
+ value.start = serialize_iso(value.start)
+ value.expiry = serialize_iso(value.expiry)
+ identifiers.append(SignedIdentifier(id=key, access_policy=value)) # type: ignore
+ signed_identifiers = identifiers # type: ignore
+ lease = kwargs.pop('lease', None)
+ mod_conditions = get_modify_conditions(kwargs)
+ access_conditions = get_access_conditions(lease)
+ timeout = kwargs.pop('timeout', None)
+ try:
+ return self._client.container.set_access_policy(
+ container_acl=signed_identifiers or None,
+ timeout=timeout,
+ access=public_access,
+ lease_access_conditions=access_conditions,
+ modified_access_conditions=mod_conditions,
+ cls=return_response_headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ @distributed_trace
+ def list_blobs(self, name_starts_with=None, include=None, **kwargs):
+ # type: (Optional[str], Optional[Union[str, List[str]]], **Any) -> ItemPaged[BlobProperties]
+ """Returns a generator to list the blobs under the specified container.
+ The generator will lazily follow the continuation tokens returned by
+ the service.
+
+ :param str name_starts_with:
+ Filters the results to return only blobs whose names
+ 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', 'deletedwithversions',
+ 'tags', 'versions', 'immutabilitypolicy', 'legalhold'.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: An iterable (auto-paging) response of BlobProperties.
+ :rtype: ~azure.core.paging.ItemPaged[~azure.storage.blob.BlobProperties]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START list_blobs_in_container]
+ :end-before: [END list_blobs_in_container]
+ :language: python
+ :dedent: 8
+ :caption: List the blobs in the container.
+ """
+ if include and not isinstance(include, list):
+ include = [include]
+
+ results_per_page = kwargs.pop('results_per_page', None)
+ timeout = kwargs.pop('timeout', None)
+ command = functools.partial(
+ self._client.container.list_blob_flat_segment,
+ include=include,
+ timeout=timeout,
+ **kwargs)
+ return ItemPaged(
+ command, prefix=name_starts_with, results_per_page=results_per_page,
+ page_iterator_class=BlobPropertiesPaged)
+
+ @distributed_trace
+ def walk_blobs(
+ self, name_starts_with=None, # type: Optional[str]
+ include=None, # type: Optional[Any]
+ delimiter="/", # type: str
+ **kwargs # type: Optional[Any]
+ ):
+ # type: (...) -> ItemPaged[BlobProperties]
+ """Returns a generator to list the blobs under the specified container.
+ The generator will lazily follow the continuation tokens returned by
+ the service. This operation will list blobs in accordance with a hierarchy,
+ as delimited by the specified delimiter character.
+
+ :param str name_starts_with:
+ Filters the results to return only blobs whose names
+ begin with the specified prefix.
+ :param list[str] include:
+ Specifies one or more additional datasets to include in the response.
+ Options include: 'snapshots', 'metadata', 'uncommittedblobs', 'copy', 'deleted'.
+ :param str delimiter:
+ When the request includes this parameter, the operation returns a BlobPrefix
+ element in the response body that acts as a placeholder for all blobs whose
+ names begin with the same substring up to the appearance of the delimiter
+ character. The delimiter may be a single character or a string.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: An iterable (auto-paging) response of BlobProperties.
+ :rtype: ~azure.core.paging.ItemPaged[~azure.storage.blob.BlobProperties]
+ """
+ if include and not isinstance(include, list):
+ include = [include]
+
+ results_per_page = kwargs.pop('results_per_page', None)
+ timeout = kwargs.pop('timeout', None)
+ command = functools.partial(
+ self._client.container.list_blob_hierarchy_segment,
+ delimiter=delimiter,
+ include=include,
+ timeout=timeout,
+ **kwargs)
+ return BlobPrefix(
+ command,
+ prefix=name_starts_with,
+ results_per_page=results_per_page,
+ delimiter=delimiter)
+
+ @distributed_trace
+ def find_blobs_by_tags(
+ self, filter_expression, # type: str
+ **kwargs # type: Optional[Any]
+ ):
+ # type: (...) -> ItemPaged[FilteredBlob]
+ """Returns a generator to list the blobs under the specified container whose tags
+ match the given search expression.
+ The generator will lazily follow the continuation tokens returned by
+ the service.
+
+ :param str filter_expression:
+ The expression to find blobs whose tags matches the specified condition.
+ eg. "\"yourtagname\"='firsttag' and \"yourtagname2\"='secondtag'"
+ :keyword int results_per_page:
+ The max result per page when paginating.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :returns: An iterable (auto-paging) response of FilteredBlob.
+ :rtype: ~azure.core.paging.ItemPaged[~azure.storage.blob.BlobProperties]
+ """
+ results_per_page = kwargs.pop('results_per_page', None)
+ timeout = kwargs.pop('timeout', None)
+ command = functools.partial(
+ self._client.container.filter_blobs,
+ timeout=timeout,
+ where=filter_expression,
+ **kwargs)
+ return ItemPaged(
+ command, results_per_page=results_per_page,
+ page_iterator_class=FilteredBlobPaged)
+
+ @distributed_trace
+ def upload_blob(
+ self, name, # type: Union[str, BlobProperties]
+ data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
+ blob_type=BlobType.BlockBlob, # type: Union[str, BlobType]
+ length=None, # type: Optional[int]
+ metadata=None, # type: Optional[Dict[str, str]]
+ **kwargs
+ ):
+ # type: (...) -> BlobClient
+ """Creates a new blob from a data source with automatic chunking.
+
+ :param name: The blob with which to interact. If specified, this value will override
+ a blob value specified in the blob URL.
+ :type name: str or ~azure.storage.blob.BlobProperties
+ :param data: The blob data to upload.
+ :param ~azure.storage.blob.BlobType blob_type: The type of the blob. This can be
+ either BlockBlob, PageBlob or AppendBlob. The default value is BlockBlob.
+ :param int length:
+ Number of bytes to read from the stream. This is optional, but
+ should be supplied for optimal performance.
+ :param metadata:
+ Name-value pairs associated with the blob as metadata.
+ :type metadata: dict(str, str)
+ :keyword bool overwrite: Whether the blob to be uploaded should overwrite the current data.
+ If True, upload_blob will overwrite the existing data. If set to False, the
+ operation will fail with ResourceExistsError. The exception to the above is with Append
+ blob types: if set to False and the data already exists, an error will not be raised
+ and the data will be appended to the existing blob. If set overwrite=True, then the existing
+ append blob will be deleted, and a new one created. Defaults to False.
+ :keyword ~azure.storage.blob.ContentSettings content_settings:
+ ContentSettings object used to set blob properties. Used to set content type, encoding,
+ language, disposition, md5, and cache control.
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash for each chunk of the blob. The storage
+ service checks the hash of the content that has arrived with the hash
+ that was sent. This is primarily valuable for detecting bitflips on
+ the wire if using http instead of https, as https (the default), will
+ already validate. Note that this MD5 hash is not stored with the
+ blob. Also note that if enabled, the memory-efficient upload algorithm
+ will not be used, because computing the MD5 hash requires buffering
+ entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
+ :keyword lease:
+ Required if the container has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds. This method may make
+ multiple calls to the Azure service and the timeout will apply to
+ each call individually.
+ :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier:
+ A page blob tier value to set the blob to. The tier correlates to the size of the
+ blob and number of allowed IOPS. This is only applicable to page blobs on
+ premium storage accounts.
+ :keyword ~azure.storage.blob.StandardBlobTier standard_blob_tier:
+ A standard blob tier value to set the blob to. For this version of the library,
+ this is only applicable to block blobs on standard storage accounts.
+ :keyword int maxsize_condition:
+ Optional conditional header. The max length in bytes permitted for
+ the append blob. If the Append Block operation would cause the blob
+ to exceed that limit or if the blob size is already greater than the
+ value specified in this header, the request will fail with
+ MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed).
+ :keyword int max_concurrency:
+ Maximum number of parallel connections to use when the blob size exceeds
+ 64MB.
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+
+ .. versionadded:: 12.2.0
+
+ :keyword str encoding:
+ Defaults to UTF-8.
+ :returns: A BlobClient to interact with the newly uploaded blob.
+ :rtype: ~azure.storage.blob.BlobClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START upload_blob_to_container]
+ :end-before: [END upload_blob_to_container]
+ :language: python
+ :dedent: 8
+ :caption: Upload blob to the container.
+ """
+ blob = self.get_blob_client(name)
+ kwargs.setdefault('merge_span', True)
+ timeout = kwargs.pop('timeout', None)
+ encoding = kwargs.pop('encoding', 'UTF-8')
+ blob.upload_blob(
+ data,
+ blob_type=blob_type,
+ length=length,
+ metadata=metadata,
+ timeout=timeout,
+ encoding=encoding,
+ **kwargs
+ )
+ return blob
+
+ @distributed_trace
+ def delete_blob(
+ self, blob, # type: Union[str, BlobProperties]
+ delete_snapshots=None, # type: Optional[str]
+ **kwargs
+ ):
+ # type: (...) -> None
+ """Marks the specified blob or snapshot for deletion.
+
+ The blob is later deleted during garbage collection.
+ Note that in order to delete a blob, you must delete all of its
+ snapshots. You can delete both at the same time with the delete_blob
+ operation.
+
+ If a delete retention policy is enabled for the service, then this operation soft deletes the blob or snapshot
+ and retains the blob or snapshot for specified number of days.
+ After specified number of days, blob's data is removed from the service during garbage collection.
+ Soft deleted blob or snapshot is accessible through :func:`list_blobs()` specifying `include=["deleted"]`
+ option. Soft-deleted blob or snapshot can be restored using :func:`~BlobClient.undelete()`
+
+ :param blob: The blob with which to interact. If specified, this value will override
+ a blob value specified in the blob URL.
+ :type blob: str or ~azure.storage.blob.BlobProperties
+ :param str delete_snapshots:
+ Required if the blob has associated snapshots. Values include:
+ - "only": Deletes only the blobs snapshots.
+ - "include": Deletes the blob along with all snapshots.
+ :keyword str version_id:
+ The version id parameter is an opaque DateTime
+ value that, when present, specifies the version of the blob to delete.
+
+ .. versionadded:: 12.4.0
+ This keyword argument was introduced in API version '2019-12-12'.
+
+ :keyword lease:
+ Required if the blob has an active lease. Value can be a BlobLeaseClient object
+ or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: None
+ """
+ blob_client = self.get_blob_client(blob) # type: ignore
+ kwargs.setdefault('merge_span', True)
+ timeout = kwargs.pop('timeout', None)
+ blob_client.delete_blob( # type: ignore
+ delete_snapshots=delete_snapshots,
+ timeout=timeout,
+ **kwargs)
+
+ @distributed_trace
+ def download_blob(self, blob, offset=None, length=None, **kwargs):
+ # type: (Union[str, BlobProperties], Optional[int], Optional[int], **Any) -> StorageStreamDownloader
+ """Downloads a blob to the StorageStreamDownloader. The readall() method must
+ be used to read all the content or readinto() must be used to download the blob into
+ a stream. Using chunks() returns an iterator which allows the user to iterate over the content in chunks.
+
+ :param blob: The blob with which to interact. If specified, this value will override
+ a blob value specified in the blob URL.
+ :type blob: str or ~azure.storage.blob.BlobProperties
+ :param int offset:
+ Start of byte range to use for downloading a section of the blob.
+ Must be set if length is provided.
+ :param int length:
+ Number of bytes to read from the stream. This is optional, but
+ should be supplied for optimal performance.
+ :keyword str version_id:
+ The version id parameter is an opaque DateTime
+ value that, when present, specifies the version of the blob to download.
+
+ .. versionadded:: 12.4.0
+ This keyword argument was introduced in API version '2019-12-12'.
+
+ :keyword bool validate_content:
+ If true, calculates an MD5 hash for each chunk of the blob. The storage
+ service checks the hash of the content that has arrived with the hash
+ that was sent. This is primarily valuable for detecting bitflips on
+ the wire if using http instead of https, as https (the default), will
+ already validate. Note that this MD5 hash is not stored with the
+ blob. Also note that if enabled, the memory-efficient upload algorithm
+ will not be used because computing the MD5 hash requires buffering
+ entire blocks, and doing so defeats the purpose of the memory-efficient algorithm.
+ :keyword lease:
+ Required if the blob has an active lease. If specified, download_blob only
+ succeeds if the blob's lease is active and matches this ID. Value can be a
+ BlobLeaseClient object or the lease ID as a string.
+ :paramtype lease: ~azure.storage.blob.BlobLeaseClient or str
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk:
+ Encrypts the data on the service-side with the given key.
+ Use of customer-provided keys must be done over HTTPS.
+ As the encryption key itself is provided in the request,
+ a secure connection must be established to transfer the key.
+ :keyword int max_concurrency:
+ The number of parallel connections with which to download.
+ :keyword str encoding:
+ Encoding to decode the downloaded bytes. Default is None, i.e. no decoding.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds. This method may make
+ multiple calls to the Azure service and the timeout will apply to
+ each call individually.
+ :returns: A streaming object (StorageStreamDownloader)
+ :rtype: ~azure.storage.blob.StorageStreamDownloader
+ """
+ blob_client = self.get_blob_client(blob) # type: ignore
+ kwargs.setdefault('merge_span', True)
+ return blob_client.download_blob(offset=offset, length=length, **kwargs)
+
+ def _generate_delete_blobs_subrequest_options(
+ self, snapshot=None,
+ delete_snapshots=None,
+ lease_access_conditions=None,
+ modified_access_conditions=None,
+ **kwargs
+ ):
+ """This code is a copy from _generated.
+
+ Once Autorest is able to provide request preparation this code should be removed.
+ """
+ lease_id = None
+ if lease_access_conditions is not None:
+ lease_id = lease_access_conditions.lease_id
+ if_modified_since = None
+ if modified_access_conditions is not None:
+ if_modified_since = modified_access_conditions.if_modified_since
+ if_unmodified_since = None
+ if modified_access_conditions is not None:
+ if_unmodified_since = modified_access_conditions.if_unmodified_since
+ if_match = None
+ if modified_access_conditions is not None:
+ if_match = modified_access_conditions.if_match
+ if_none_match = None
+ if modified_access_conditions is not None:
+ if_none_match = modified_access_conditions.if_none_match
+ if_tags = None
+ if modified_access_conditions is not None:
+ if_tags = modified_access_conditions.if_tags
+
+ # Construct parameters
+ timeout = kwargs.pop('timeout', None)
+ query_parameters = {}
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._client._serialize.query("snapshot", snapshot, 'str') # pylint: disable=protected-access
+ if timeout is not None:
+ query_parameters['timeout'] = self._client._serialize.query("timeout", timeout, 'int', minimum=0) # pylint: disable=protected-access
+
+ # Construct headers
+ header_parameters = {}
+ if delete_snapshots is not None:
+ header_parameters['x-ms-delete-snapshots'] = self._client._serialize.header( # pylint: disable=protected-access
+ "delete_snapshots", delete_snapshots, 'DeleteSnapshotsOptionType')
+ if lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._client._serialize.header( # pylint: disable=protected-access
+ "lease_id", lease_id, 'str')
+ if if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._client._serialize.header( # pylint: disable=protected-access
+ "if_modified_since", if_modified_since, 'rfc-1123')
+ if if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._client._serialize.header( # pylint: disable=protected-access
+ "if_unmodified_since", if_unmodified_since, 'rfc-1123')
+ if if_match is not None:
+ header_parameters['If-Match'] = self._client._serialize.header( # pylint: disable=protected-access
+ "if_match", if_match, 'str')
+ if if_none_match is not None:
+ header_parameters['If-None-Match'] = self._client._serialize.header( # pylint: disable=protected-access
+ "if_none_match", if_none_match, 'str')
+ if if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._client._serialize.header("if_tags", if_tags, 'str') # pylint: disable=protected-access
+
+ return query_parameters, header_parameters
+
+ def _generate_delete_blobs_options(self,
+ *blobs, # type: List[Union[str, BlobProperties, dict]]
+ **kwargs
+ ):
+ timeout = kwargs.pop('timeout', None)
+ raise_on_any_failure = kwargs.pop('raise_on_any_failure', True)
+ delete_snapshots = kwargs.pop('delete_snapshots', None)
+ if_modified_since = kwargs.pop('if_modified_since', None)
+ if_unmodified_since = kwargs.pop('if_unmodified_since', None)
+ if_tags_match_condition = kwargs.pop('if_tags_match_condition', None)
+ kwargs.update({'raise_on_any_failure': raise_on_any_failure,
+ 'sas': self._query_str.replace('?', '&'),
+ 'timeout': '&timeout=' + str(timeout) if timeout else "",
+ 'path': self.container_name,
+ 'restype': 'restype=container&'
+ })
+
+ reqs = []
+ for blob in blobs:
+ blob_name = _get_blob_name(blob)
+ container_name = self.container_name
+
+ try:
+ options = BlobClient._generic_delete_blob_options( # pylint: disable=protected-access
+ snapshot=blob.get('snapshot'),
+ delete_snapshots=delete_snapshots or blob.get('delete_snapshots'),
+ lease=blob.get('lease_id'),
+ if_modified_since=if_modified_since or blob.get('if_modified_since'),
+ if_unmodified_since=if_unmodified_since or blob.get('if_unmodified_since'),
+ etag=blob.get('etag'),
+ if_tags_match_condition=if_tags_match_condition or blob.get('if_tags_match_condition'),
+ match_condition=blob.get('match_condition') or MatchConditions.IfNotModified if blob.get('etag')
+ else None,
+ timeout=blob.get('timeout'),
+ )
+ except AttributeError:
+ options = BlobClient._generic_delete_blob_options( # pylint: disable=protected-access
+ delete_snapshots=delete_snapshots,
+ if_modified_since=if_modified_since,
+ if_unmodified_since=if_unmodified_since,
+ if_tags_match_condition=if_tags_match_condition
+ )
+
+ query_parameters, header_parameters = self._generate_delete_blobs_subrequest_options(**options)
+
+ req = HttpRequest(
+ "DELETE",
+ "/{}/{}{}".format(quote(container_name), quote(blob_name, safe='/~'), self._query_str),
+ headers=header_parameters
+ )
+ req.format_parameters(query_parameters)
+ reqs.append(req)
+
+ return reqs, kwargs
+
+ @distributed_trace
+ def delete_blobs(self, *blobs, **kwargs):
+ # type: (...) -> Iterator[HttpResponse]
+ """Marks the specified blobs or snapshots for deletion.
+
+ The blobs are later deleted during garbage collection.
+ Note that in order to delete blobs, you must delete all of their
+ snapshots. You can delete both at the same time with the delete_blobs operation.
+
+ If a delete retention policy is enabled for the service, then this operation soft deletes the blobs or snapshots
+ and retains the blobs or snapshots for specified number of days.
+ After specified number of days, blobs' data is removed from the service during garbage collection.
+ Soft deleted blobs or snapshots are accessible through :func:`list_blobs()` specifying `include=["deleted"]`
+ Soft-deleted blobs or snapshots can be restored using :func:`~BlobClient.undelete()`
+
+ The maximum number of blobs that can be deleted in a single request is 256.
+
+ :param blobs:
+ The blobs to delete. This can be a single blob, or multiple values can
+ be supplied, where each value is either the name of the blob (str) or BlobProperties.
+
+ .. note::
+ When the blob type is dict, here's a list of keys, value rules.
+
+ blob name:
+ key: 'name', value type: str
+ snapshot you want to delete:
+ key: 'snapshot', value type: str
+ whether to delete snapthots when deleting blob:
+ key: 'delete_snapshots', value: 'include' or 'only'
+ if the blob modified or not:
+ key: 'if_modified_since', 'if_unmodified_since', value type: datetime
+ etag:
+ key: 'etag', value type: str
+ match the etag or not:
+ key: 'match_condition', value type: MatchConditions
+ tags match condition:
+ key: 'if_tags_match_condition', value type: str
+ lease:
+ key: 'lease_id', value type: Union[str, LeaseClient]
+ timeout for subrequest:
+ key: 'timeout', value type: int
+
+ :type blobs: list[str], list[dict], or list[~azure.storage.blob.BlobProperties]
+ :keyword str delete_snapshots:
+ Required if a blob has associated snapshots. Values include:
+ - "only": Deletes only the blobs snapshots.
+ - "include": Deletes the blob along with all snapshots.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword bool raise_on_any_failure:
+ This is a boolean param which defaults to True. When this is set, an exception
+ is raised even if there is a single operation failure.
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :return: An iterator of responses, one for each blob in order
+ :rtype: Iterator[~azure.core.pipeline.transport.HttpResponse]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_common.py
+ :start-after: [START delete_multiple_blobs]
+ :end-before: [END delete_multiple_blobs]
+ :language: python
+ :dedent: 8
+ :caption: Deleting multiple blobs.
+ """
+ if len(blobs) == 0:
+ return iter(list())
+
+ reqs, options = self._generate_delete_blobs_options(*blobs, **kwargs)
+
+ return self._batch_send(*reqs, **options)
+
+ def _generate_set_tiers_subrequest_options(
+ self, tier, snapshot=None, version_id=None, rehydrate_priority=None, lease_access_conditions=None, **kwargs
+ ):
+ """This code is a copy from _generated.
+
+ Once Autorest is able to provide request preparation this code should be removed.
+ """
+ if not tier:
+ raise ValueError("A blob tier must be specified")
+ if snapshot and version_id:
+ raise ValueError("Snapshot and version_id cannot be set at the same time")
+ if_tags = kwargs.pop('if_tags', None)
+
+ lease_id = None
+ if lease_access_conditions is not None:
+ lease_id = lease_access_conditions.lease_id
+
+ comp = "tier"
+ timeout = kwargs.pop('timeout', None)
+ # Construct parameters
+ query_parameters = {}
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._client._serialize.query("snapshot", snapshot, 'str') # pylint: disable=protected-access
+ if version_id is not None:
+ query_parameters['versionid'] = self._client._serialize.query("version_id", version_id, 'str') # pylint: disable=protected-access
+ if timeout is not None:
+ query_parameters['timeout'] = self._client._serialize.query("timeout", timeout, 'int', minimum=0) # pylint: disable=protected-access
+ query_parameters['comp'] = self._client._serialize.query("comp", comp, 'str') # pylint: disable=protected-access, specify-parameter-names-in-call
+
+ # Construct headers
+ header_parameters = {}
+ header_parameters['x-ms-access-tier'] = self._client._serialize.header("tier", tier, 'str') # pylint: disable=protected-access, specify-parameter-names-in-call
+ if rehydrate_priority is not None:
+ header_parameters['x-ms-rehydrate-priority'] = self._client._serialize.header( # pylint: disable=protected-access
+ "rehydrate_priority", rehydrate_priority, 'str')
+ if lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._client._serialize.header("lease_id", lease_id, 'str') # pylint: disable=protected-access
+ if if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._client._serialize.header("if_tags", if_tags, 'str') # pylint: disable=protected-access
+
+ return query_parameters, header_parameters
+
+ def _generate_set_tiers_options(self,
+ blob_tier, # type: Optional[Union[str, StandardBlobTier, PremiumPageBlobTier]]
+ *blobs, # type: List[Union[str, BlobProperties, dict]]
+ **kwargs
+ ):
+ timeout = kwargs.pop('timeout', None)
+ raise_on_any_failure = kwargs.pop('raise_on_any_failure', True)
+ rehydrate_priority = kwargs.pop('rehydrate_priority', None)
+ if_tags = kwargs.pop('if_tags_match_condition', None)
+ kwargs.update({'raise_on_any_failure': raise_on_any_failure,
+ 'sas': self._query_str.replace('?', '&'),
+ 'timeout': '&timeout=' + str(timeout) if timeout else "",
+ 'path': self.container_name,
+ 'restype': 'restype=container&'
+ })
+
+ reqs = []
+ for blob in blobs:
+ blob_name = _get_blob_name(blob)
+ container_name = self.container_name
+
+ try:
+ tier = blob_tier or blob.get('blob_tier')
+ query_parameters, header_parameters = self._generate_set_tiers_subrequest_options(
+ tier=tier,
+ snapshot=blob.get('snapshot'),
+ version_id=blob.get('version_id'),
+ rehydrate_priority=rehydrate_priority or blob.get('rehydrate_priority'),
+ lease_access_conditions=blob.get('lease_id'),
+ if_tags=if_tags or blob.get('if_tags_match_condition'),
+ timeout=timeout or blob.get('timeout')
+ )
+ except AttributeError:
+ query_parameters, header_parameters = self._generate_set_tiers_subrequest_options(
+ blob_tier, rehydrate_priority=rehydrate_priority, if_tags=if_tags)
+
+ req = HttpRequest(
+ "PUT",
+ "/{}/{}{}".format(quote(container_name), quote(blob_name, safe='/~'), self._query_str),
+ headers=header_parameters
+ )
+ req.format_parameters(query_parameters)
+ reqs.append(req)
+
+ return reqs, kwargs
+
+ @distributed_trace
+ def set_standard_blob_tier_blobs(
+ self,
+ standard_blob_tier, # type: Optional[Union[str, StandardBlobTier]]
+ *blobs, # type: List[Union[str, BlobProperties, dict]]
+ **kwargs
+ ):
+ # type: (...) -> Iterator[HttpResponse]
+ """This operation sets the tier on block blobs.
+
+ A block blob's tier determines Hot/Cool/Archive storage type.
+ This operation does not update the blob's ETag.
+
+ The maximum number of blobs that can be updated in a single request is 256.
+
+ :param standard_blob_tier:
+ Indicates the tier to be set on all blobs. Options include 'Hot', 'Cool',
+ 'Archive'. The hot tier is optimized for storing data that is accessed
+ frequently. The cool storage tier is optimized for storing data that
+ is infrequently accessed and stored for at least a month. The archive
+ tier is optimized for storing data that is rarely accessed and stored
+ for at least six months with flexible latency requirements.
+
+ .. note::
+ If you want to set different tier on different blobs please set this positional parameter to None.
+ Then the blob tier on every BlobProperties will be taken.
+
+ :type standard_blob_tier: str or ~azure.storage.blob.StandardBlobTier
+ :param blobs:
+ The blobs with which to interact. This can be a single blob, or multiple values can
+ be supplied, where each value is either the name of the blob (str) or BlobProperties.
+
+ .. note::
+ When the blob type is dict, here's a list of keys, value rules.
+
+ blob name:
+ key: 'name', value type: str
+ standard blob tier:
+ key: 'blob_tier', value type: StandardBlobTier
+ rehydrate priority:
+ key: 'rehydrate_priority', value type: RehydratePriority
+ lease:
+ key: 'lease_id', value type: Union[str, LeaseClient]
+ snapshot:
+ key: "snapshost", value type: str
+ version id:
+ key: "version_id", value type: str
+ tags match condition:
+ key: 'if_tags_match_condition', value type: str
+ timeout for subrequest:
+ key: 'timeout', value type: int
+
+ :type blobs: list[str], list[dict], or list[~azure.storage.blob.BlobProperties]
+ :keyword ~azure.storage.blob.RehydratePriority rehydrate_priority:
+ Indicates the priority with which to rehydrate an archived blob
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :keyword bool raise_on_any_failure:
+ This is a boolean param which defaults to True. When this is set, an exception
+ is raised even if there is a single operation failure.
+ :return: An iterator of responses, one for each blob in order
+ :rtype: Iterator[~azure.core.pipeline.transport.HttpResponse]
+ """
+ reqs, options = self._generate_set_tiers_options(standard_blob_tier, *blobs, **kwargs)
+
+ return self._batch_send(*reqs, **options)
+
+ @distributed_trace
+ def set_premium_page_blob_tier_blobs(
+ self,
+ premium_page_blob_tier, # type: Optional[Union[str, PremiumPageBlobTier]]
+ *blobs, # type: List[Union[str, BlobProperties, dict]]
+ **kwargs
+ ):
+ # type: (...) -> Iterator[HttpResponse]
+ """Sets the page blob tiers on all blobs. This API is only supported for page blobs on premium accounts.
+
+ The maximum number of blobs that can be updated in a single request is 256.
+
+ :param premium_page_blob_tier:
+ A page blob tier value to set the blob to. The tier correlates to the size of the
+ blob and number of allowed IOPS. This is only applicable to page blobs on
+ premium storage accounts.
+
+ .. note::
+ If you want to set different tier on different blobs please set this positional parameter to None.
+ Then the blob tier on every BlobProperties will be taken.
+
+ :type premium_page_blob_tier: ~azure.storage.blob.PremiumPageBlobTier
+ :param blobs:
+ The blobs with which to interact. This can be a single blob, or multiple values can
+ be supplied, where each value is either the name of the blob (str) or BlobProperties.
+
+ .. note::
+ When the blob type is dict, here's a list of keys, value rules.
+
+ blob name:
+ key: 'name', value type: str
+ premium blob tier:
+ key: 'blob_tier', value type: PremiumPageBlobTier
+ lease:
+ key: 'lease_id', value type: Union[str, LeaseClient]
+ timeout for subrequest:
+ key: 'timeout', value type: int
+
+ :type blobs: list[str], list[dict], or list[~azure.storage.blob.BlobProperties]
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds. This method may make
+ multiple calls to the Azure service and the timeout will apply to
+ each call individually.
+ :keyword bool raise_on_any_failure:
+ This is a boolean param which defaults to True. When this is set, an exception
+ is raised even if there is a single operation failure.
+ :return: An iterator of responses, one for each blob in order
+ :rtype: iterator[~azure.core.pipeline.transport.HttpResponse]
+ """
+ reqs, options = self._generate_set_tiers_options(premium_page_blob_tier, *blobs, **kwargs)
+
+ return self._batch_send(*reqs, **options)
+
+ def get_blob_client(
+ self, blob, # type: Union[str, BlobProperties]
+ snapshot=None # type: str
+ ):
+ # type: (...) -> BlobClient
+ """Get a client to interact with the specified blob.
+
+ The blob need not already exist.
+
+ :param blob:
+ The blob with which to interact.
+ :type blob: str or ~azure.storage.blob.BlobProperties
+ :param str snapshot:
+ The optional blob snapshot on which to operate. This can be the snapshot ID string
+ or the response returned from :func:`~BlobClient.create_snapshot()`.
+ :returns: A BlobClient.
+ :rtype: ~azure.storage.blob.BlobClient
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START get_blob_client]
+ :end-before: [END get_blob_client]
+ :language: python
+ :dedent: 8
+ :caption: Get the blob client.
+ """
+ blob_name = _get_blob_name(blob)
+ _pipeline = Pipeline(
+ transport=TransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
+ policies=self._pipeline._impl_policies # pylint: disable = protected-access
+ )
+ return BlobClient(
+ self.url, container_name=self.container_name, blob_name=blob_name, snapshot=snapshot,
+ credential=self.credential, api_version=self.api_version, _configuration=self._config,
+ _pipeline=_pipeline, _location_mode=self._location_mode, _hosts=self._hosts,
+ require_encryption=self.require_encryption, key_encryption_key=self.key_encryption_key,
+ key_resolver_function=self.key_resolver_function)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_deserialize.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_deserialize.py
new file mode 100644
index 00000000000..f7101e05d6a
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_deserialize.py
@@ -0,0 +1,174 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=no-self-use
+from typing import ( # pylint: disable=unused-import
+ Tuple, Dict, List,
+ TYPE_CHECKING
+)
+try:
+ from urllib.parse import unquote
+except ImportError:
+ from urllib import unquote
+from ._models import BlobType, CopyProperties, ContentSettings, LeaseProperties, BlobProperties, ImmutabilityPolicy
+from ._shared.models import get_enum_value
+from ._shared.response_handlers import deserialize_metadata
+from ._models import ContainerProperties, BlobAnalyticsLogging, Metrics, CorsRule, RetentionPolicy, \
+ StaticWebsite, ObjectReplicationPolicy, ObjectReplicationRule
+
+if TYPE_CHECKING:
+ from ._generated.models import PageList
+
+
+def deserialize_pipeline_response_into_cls(cls_method, response, obj, headers):
+ try:
+ deserialized_response = response.http_response
+ except AttributeError:
+ deserialized_response = response
+ return cls_method(deserialized_response, obj, headers)
+
+
+def deserialize_blob_properties(response, obj, headers):
+ blob_properties = BlobProperties(
+ metadata=deserialize_metadata(response, obj, headers),
+ object_replication_source_properties=deserialize_ors_policies(response.http_response.headers),
+ **headers
+ )
+ if 'Content-Range' in headers:
+ if 'x-ms-blob-content-md5' in headers:
+ blob_properties.content_settings.content_md5 = headers['x-ms-blob-content-md5']
+ else:
+ blob_properties.content_settings.content_md5 = None
+ return blob_properties
+
+
+def deserialize_ors_policies(policy_dictionary):
+
+ if policy_dictionary is None:
+ return None
+ # For source blobs (blobs that have policy ids and rule ids applied to them),
+ # the header will be formatted as "x-ms-or-_: {Complete, Failed}".
+ # The value of this header is the status of the replication.
+ or_policy_status_headers = {key: val for key, val in policy_dictionary.items()
+ if 'or-' in key and key != 'x-ms-or-policy-id'}
+
+ parsed_result = {}
+
+ for key, val in or_policy_status_headers.items():
+ # list blobs gives or-policy_rule and get blob properties gives x-ms-or-policy_rule
+ policy_and_rule_ids = key.split('or-')[1].split('_')
+ policy_id = policy_and_rule_ids[0]
+ rule_id = policy_and_rule_ids[1]
+
+ # If we are seeing this policy for the first time, create a new list to store rule_id -> result
+ parsed_result[policy_id] = parsed_result.get(policy_id) or list()
+ parsed_result[policy_id].append(ObjectReplicationRule(rule_id=rule_id, status=val))
+
+ result_list = [ObjectReplicationPolicy(policy_id=k, rules=v) for k, v in parsed_result.items()]
+
+ return result_list
+
+
+def deserialize_blob_stream(response, obj, headers):
+ blob_properties = deserialize_blob_properties(response, obj, headers)
+ obj.properties = blob_properties
+ return response.http_response.location_mode, obj
+
+
+def deserialize_container_properties(response, obj, headers):
+ metadata = deserialize_metadata(response, obj, headers)
+ container_properties = ContainerProperties(
+ metadata=metadata,
+ **headers
+ )
+ return container_properties
+
+
+def get_page_ranges_result(ranges):
+ # type: (PageList) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]
+ page_range = [] # type: ignore
+ clear_range = [] # type: List
+ if ranges.page_range:
+ page_range = [{'start': b.start, 'end': b.end} for b in ranges.page_range] # type: ignore
+ if ranges.clear_range:
+ clear_range = [{'start': b.start, 'end': b.end} for b in ranges.clear_range]
+ return page_range, clear_range # type: ignore
+
+
+def service_stats_deserialize(generated):
+ """Deserialize a ServiceStats objects into a dict.
+ """
+ return {
+ 'geo_replication': {
+ 'status': generated.geo_replication.status,
+ 'last_sync_time': generated.geo_replication.last_sync_time,
+ }
+ }
+
+
+def service_properties_deserialize(generated):
+ """Deserialize a ServiceProperties objects into a dict.
+ """
+ return {
+ 'analytics_logging': BlobAnalyticsLogging._from_generated(generated.logging), # pylint: disable=protected-access
+ 'hour_metrics': Metrics._from_generated(generated.hour_metrics), # pylint: disable=protected-access
+ 'minute_metrics': Metrics._from_generated(generated.minute_metrics), # pylint: disable=protected-access
+ 'cors': [CorsRule._from_generated(cors) for cors in generated.cors], # pylint: disable=protected-access
+ 'target_version': generated.default_service_version, # pylint: disable=protected-access
+ 'delete_retention_policy': RetentionPolicy._from_generated(generated.delete_retention_policy), # pylint: disable=protected-access
+ 'static_website': StaticWebsite._from_generated(generated.static_website), # pylint: disable=protected-access
+ }
+
+
+def get_blob_properties_from_generated_code(generated):
+ blob = BlobProperties()
+ if generated.name.encoded:
+ blob.name = unquote(generated.name.content)
+ else:
+ blob.name = generated.name.content
+ blob_type = get_enum_value(generated.properties.blob_type)
+ blob.blob_type = BlobType(blob_type) if blob_type else None
+ blob.etag = generated.properties.etag
+ blob.deleted = generated.deleted
+ blob.snapshot = generated.snapshot
+ blob.is_append_blob_sealed = generated.properties.is_sealed
+ blob.metadata = generated.metadata.additional_properties if generated.metadata else {}
+ blob.encrypted_metadata = generated.metadata.encrypted if generated.metadata else None
+ blob.lease = LeaseProperties._from_generated(generated) # pylint: disable=protected-access
+ blob.copy = CopyProperties._from_generated(generated) # pylint: disable=protected-access
+ blob.last_modified = generated.properties.last_modified
+ blob.creation_time = generated.properties.creation_time
+ blob.content_settings = ContentSettings._from_generated(generated) # pylint: disable=protected-access
+ blob.size = generated.properties.content_length
+ blob.page_blob_sequence_number = generated.properties.blob_sequence_number
+ blob.server_encrypted = generated.properties.server_encrypted
+ blob.encryption_scope = generated.properties.encryption_scope
+ blob.deleted_time = generated.properties.deleted_time
+ blob.remaining_retention_days = generated.properties.remaining_retention_days
+ blob.blob_tier = generated.properties.access_tier
+ blob.rehydrate_priority = generated.properties.rehydrate_priority
+ blob.blob_tier_inferred = generated.properties.access_tier_inferred
+ blob.archive_status = generated.properties.archive_status
+ blob.blob_tier_change_time = generated.properties.access_tier_change_time
+ blob.version_id = generated.version_id
+ blob.is_current_version = generated.is_current_version
+ blob.tag_count = generated.properties.tag_count
+ 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.immutability_policy = ImmutabilityPolicy._from_generated(generated) # pylint: disable=protected-access
+ blob.has_legal_hold = generated.properties.legal_hold
+ blob.has_versions_only = generated.has_versions_only
+ return blob
+
+
+def parse_tags(generated_tags):
+ # type: (Optional[List[BlobTag]]) -> Union[Dict[str, str], None]
+ """Deserialize a list of BlobTag objects into a dict.
+ """
+ if generated_tags:
+ tag_dict = {t.key: t.value for t in generated_tags.blob_tag_set}
+ return tag_dict
+ return None
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_download.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_download.py
new file mode 100644
index 00000000000..c74af2f3ce7
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_download.py
@@ -0,0 +1,637 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import sys
+import threading
+import time
+
+import warnings
+from io import BytesIO
+from typing import Iterator
+
+import requests
+from azure.core.exceptions import HttpResponseError, ServiceResponseError
+
+from azure.core.tracing.common import with_current_context
+from ._shared.encryption import decrypt_blob
+from ._shared.request_handlers import validate_and_format_range_headers
+from ._shared.response_handlers import process_storage_error, parse_length_from_content_range
+from ._deserialize import get_page_ranges_result
+
+
+def process_range_and_offset(start_range, end_range, length, encryption):
+ start_offset, end_offset = 0, 0
+ if encryption.get("key") is not None or encryption.get("resolver") is not None:
+ if start_range is not None:
+ # Align the start of the range along a 16 byte block
+ start_offset = start_range % 16
+ start_range -= start_offset
+
+ # Include an extra 16 bytes for the IV if necessary
+ # Because of the previous offsetting, start_range will always
+ # be a multiple of 16.
+ if start_range > 0:
+ start_offset += 16
+ start_range -= 16
+
+ if length is not None:
+ # Align the end of the range along a 16 byte block
+ end_offset = 15 - (end_range % 16)
+ end_range += end_offset
+
+ return (start_range, end_range), (start_offset, end_offset)
+
+
+def process_content(data, start_offset, end_offset, encryption):
+ if data is None:
+ raise ValueError("Response cannot be None.")
+
+ content = b"".join(list(data))
+
+ if content and encryption.get("key") is not None or encryption.get("resolver") is not None:
+ try:
+ return decrypt_blob(
+ encryption.get("required"),
+ encryption.get("key"),
+ encryption.get("resolver"),
+ content,
+ start_offset,
+ end_offset,
+ data.response.headers,
+ )
+ except Exception as error:
+ raise HttpResponseError(message="Decryption failed.", response=data.response, error=error)
+ return content
+
+
+class _ChunkDownloader(object): # pylint: disable=too-many-instance-attributes
+ def __init__(
+ self,
+ client=None,
+ non_empty_ranges=None,
+ total_size=None,
+ chunk_size=None,
+ current_progress=None,
+ start_range=None,
+ end_range=None,
+ stream=None,
+ parallel=None,
+ validate_content=None,
+ encryption_options=None,
+ **kwargs
+ ):
+ self.client = client
+ self.non_empty_ranges = non_empty_ranges
+
+ # Information on the download range/chunk size
+ self.chunk_size = chunk_size
+ self.total_size = total_size
+ self.start_index = start_range
+ self.end_index = end_range
+
+ # The destination that we will write to
+ self.stream = stream
+ self.stream_lock = threading.Lock() if parallel else None
+ self.progress_lock = threading.Lock() if parallel else None
+
+ # For a parallel download, the stream is always seekable, so we note down the current position
+ # in order to seek to the right place when out-of-order chunks come in
+ self.stream_start = stream.tell() if parallel else None
+
+ # Download progress so far
+ self.progress_total = current_progress
+
+ # Encryption
+ self.encryption_options = encryption_options
+
+ # Parameters for each get operation
+ self.validate_content = validate_content
+ self.request_options = kwargs
+
+ def _calculate_range(self, chunk_start):
+ if chunk_start + self.chunk_size > self.end_index:
+ chunk_end = self.end_index
+ else:
+ chunk_end = chunk_start + self.chunk_size
+ return chunk_start, chunk_end
+
+ def get_chunk_offsets(self):
+ index = self.start_index
+ while index < self.end_index:
+ yield index
+ index += self.chunk_size
+
+ def process_chunk(self, chunk_start):
+ chunk_start, chunk_end = self._calculate_range(chunk_start)
+ chunk_data = self._download_chunk(chunk_start, chunk_end - 1)
+ length = chunk_end - chunk_start
+ if length > 0:
+ self._write_to_stream(chunk_data, chunk_start)
+ self._update_progress(length)
+
+ def yield_chunk(self, chunk_start):
+ chunk_start, chunk_end = self._calculate_range(chunk_start)
+ return self._download_chunk(chunk_start, chunk_end - 1)
+
+ def _update_progress(self, length):
+ if self.progress_lock:
+ with self.progress_lock: # pylint: disable=not-context-manager
+ self.progress_total += length
+ else:
+ self.progress_total += length
+
+ def _write_to_stream(self, chunk_data, chunk_start):
+ if self.stream_lock:
+ with self.stream_lock: # pylint: disable=not-context-manager
+ self.stream.seek(self.stream_start + (chunk_start - self.start_index))
+ self.stream.write(chunk_data)
+ else:
+ self.stream.write(chunk_data)
+
+ def _do_optimize(self, given_range_start, given_range_end):
+ # If we have no page range list stored, then assume there's data everywhere for that page blob
+ # or it's a block blob or append blob
+ if self.non_empty_ranges is None:
+ return False
+
+ for source_range in self.non_empty_ranges:
+ # Case 1: As the range list is sorted, if we've reached such a source_range
+ # we've checked all the appropriate source_range already and haven't found any overlapping.
+ # so the given range doesn't have any data and download optimization could be applied.
+ # given range: | |
+ # source range: | |
+ if given_range_end < source_range['start']: # pylint:disable=no-else-return
+ return True
+ # Case 2: the given range comes after source_range, continue checking.
+ # given range: | |
+ # source range: | |
+ elif source_range['end'] < given_range_start:
+ pass
+ # Case 3: source_range and given range overlap somehow, no need to optimize.
+ else:
+ return False
+ # Went through all src_ranges, but nothing overlapped. Optimization will be applied.
+ return True
+
+ def _download_chunk(self, chunk_start, chunk_end):
+ download_range, offset = process_range_and_offset(
+ chunk_start, chunk_end, chunk_end, self.encryption_options
+ )
+
+ # No need to download the empty chunk from server if there's no data in the chunk to be downloaded.
+ # Do optimize and create empty chunk locally if condition is met.
+ if self._do_optimize(download_range[0], download_range[1]):
+ chunk_data = b"\x00" * self.chunk_size
+ else:
+ range_header, range_validation = validate_and_format_range_headers(
+ download_range[0],
+ download_range[1],
+ check_content_md5=self.validate_content
+ )
+
+ retry_active = True
+ retry_total = 3
+ while retry_active:
+ try:
+ _, response = self.client.download(
+ range=range_header,
+ range_get_content_md5=range_validation,
+ validate_content=self.validate_content,
+ data_stream_total=self.total_size,
+ download_stream_current=self.progress_total,
+ **self.request_options
+ )
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ try:
+ chunk_data = process_content(response, offset[0], offset[1], self.encryption_options)
+ retry_active = False
+ except (requests.exceptions.ChunkedEncodingError, requests.exceptions.ConnectionError) as error:
+ retry_total -= 1
+ if retry_total <= 0:
+ raise ServiceResponseError(error, error=error)
+ time.sleep(1)
+
+ # This makes sure that if_match is set so that we can validate
+ # that subsequent downloads are to an unmodified blob
+ if self.request_options.get("modified_access_conditions"):
+ self.request_options["modified_access_conditions"].if_match = response.properties.etag
+
+ return chunk_data
+
+
+class _ChunkIterator(object):
+ """Async iterator for chunks in blob download stream."""
+
+ def __init__(self, size, content, downloader, chunk_size):
+ self.size = size
+ self._chunk_size = chunk_size
+ self._current_content = content
+ self._iter_downloader = downloader
+ self._iter_chunks = None
+ self._complete = (size == 0)
+
+ def __len__(self):
+ return self.size
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ """Iterate through responses."""
+ if self._complete:
+ raise StopIteration("Download complete")
+ if not self._iter_downloader:
+ # cut the data obtained from initial GET into chunks
+ if len(self._current_content) > self._chunk_size:
+ return self._get_chunk_data()
+ self._complete = True
+ return self._current_content
+
+ if not self._iter_chunks:
+ self._iter_chunks = self._iter_downloader.get_chunk_offsets()
+
+ # initial GET result still has more than _chunk_size bytes of data
+ if len(self._current_content) >= self._chunk_size:
+ return self._get_chunk_data()
+
+ try:
+ chunk = next(self._iter_chunks)
+ self._current_content += self._iter_downloader.yield_chunk(chunk)
+ except StopIteration as e:
+ self._complete = True
+ if self._current_content:
+ return self._current_content
+ raise e
+
+ # the current content from the first get is still there but smaller than chunk size
+ # therefore we want to make sure its also included
+ return self._get_chunk_data()
+
+ next = __next__ # Python 2 compatibility.
+
+ def _get_chunk_data(self):
+ chunk_data = self._current_content[: self._chunk_size]
+ self._current_content = self._current_content[self._chunk_size:]
+ return chunk_data
+
+
+class StorageStreamDownloader(object): # pylint: disable=too-many-instance-attributes
+ """A streaming object to download from Azure Storage.
+
+ :ivar str name:
+ The name of the blob being downloaded.
+ :ivar str container:
+ The name of the container where the blob is.
+ :ivar ~azure.storage.blob.BlobProperties properties:
+ The properties of the blob being downloaded. If only a range of the data is being
+ downloaded, this will be reflected in the properties.
+ :ivar int size:
+ The size of the total data in the stream. This will be the byte range if specified,
+ otherwise the total size of the blob.
+ """
+
+ def __init__(
+ self,
+ clients=None,
+ config=None,
+ start_range=None,
+ end_range=None,
+ validate_content=None,
+ encryption_options=None,
+ max_concurrency=1,
+ name=None,
+ container=None,
+ encoding=None,
+ **kwargs
+ ):
+ self.name = name
+ self.container = container
+ self.properties = None
+ self.size = None
+
+ self._clients = clients
+ self._config = config
+ self._start_range = start_range
+ self._end_range = end_range
+ self._max_concurrency = max_concurrency
+ self._encoding = encoding
+ self._validate_content = validate_content
+ self._encryption_options = encryption_options or {}
+ self._request_options = kwargs
+ self._location_mode = None
+ self._download_complete = False
+ self._current_content = None
+ self._file_size = None
+ self._non_empty_ranges = None
+ self._response = None
+
+ # The service only provides transactional MD5s for chunks under 4MB.
+ # If validate_content is on, get only self.MAX_CHUNK_GET_SIZE for the first
+ # chunk so a transactional MD5 can be retrieved.
+ self._first_get_size = (
+ self._config.max_single_get_size if not self._validate_content else self._config.max_chunk_get_size
+ )
+ initial_request_start = self._start_range if self._start_range is not None else 0
+ if self._end_range is not None and self._end_range - self._start_range < self._first_get_size:
+ initial_request_end = self._end_range
+ else:
+ initial_request_end = initial_request_start + self._first_get_size - 1
+
+ self._initial_range, self._initial_offset = process_range_and_offset(
+ initial_request_start, initial_request_end, self._end_range, self._encryption_options
+ )
+
+ self._response = self._initial_request()
+ self.properties = self._response.properties
+ self.properties.name = self.name
+ self.properties.container = self.container
+
+ # Set the content length to the download size instead of the size of
+ # the last range
+ self.properties.size = self.size
+
+ # Overwrite the content range to the user requested range
+ self.properties.content_range = "bytes {0}-{1}/{2}".format(
+ self._start_range,
+ self._end_range,
+ self._file_size
+ )
+
+ # Overwrite the content MD5 as it is the MD5 for the last range instead
+ # of the stored MD5
+ # TODO: Set to the stored MD5 when the service returns this
+ self.properties.content_md5 = None
+
+ def __len__(self):
+ return self.size
+
+ def _initial_request(self):
+ range_header, range_validation = validate_and_format_range_headers(
+ self._initial_range[0],
+ self._initial_range[1],
+ start_range_required=False,
+ end_range_required=False,
+ check_content_md5=self._validate_content
+ )
+
+ retry_active = True
+ retry_total = 3
+ while retry_active:
+ try:
+ location_mode, response = self._clients.blob.download(
+ range=range_header,
+ range_get_content_md5=range_validation,
+ validate_content=self._validate_content,
+ data_stream_total=None,
+ download_stream_current=0,
+ **self._request_options
+ )
+
+ # Check the location we read from to ensure we use the same one
+ # for subsequent requests.
+ self._location_mode = location_mode
+
+ # Parse the total file size and adjust the download size if ranges
+ # were specified
+ self._file_size = parse_length_from_content_range(response.properties.content_range)
+ if self._end_range is not None:
+ # Use the end range index unless it is over the end of the file
+ self.size = min(self._file_size, self._end_range - self._start_range + 1)
+ elif self._start_range is not None:
+ self.size = self._file_size - self._start_range
+ else:
+ self.size = self._file_size
+
+ except HttpResponseError as error:
+ if self._start_range is None and error.response.status_code == 416:
+ # Get range will fail on an empty file. If the user did not
+ # request a range, do a regular get request in order to get
+ # any properties.
+ try:
+ _, response = self._clients.blob.download(
+ validate_content=self._validate_content,
+ data_stream_total=0,
+ download_stream_current=0,
+ **self._request_options
+ )
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ # Set the download size to empty
+ self.size = 0
+ self._file_size = 0
+ else:
+ process_storage_error(error)
+
+ try:
+ if self.size == 0:
+ self._current_content = b""
+ else:
+ self._current_content = process_content(
+ response,
+ self._initial_offset[0],
+ self._initial_offset[1],
+ self._encryption_options
+ )
+ retry_active = False
+ except (requests.exceptions.ChunkedEncodingError, requests.exceptions.ConnectionError) as error:
+ retry_total -= 1
+ if retry_total <= 0:
+ raise ServiceResponseError(error, error=error)
+ time.sleep(1)
+
+ # get page ranges to optimize downloading sparse page blob
+ if response.properties.blob_type == 'PageBlob':
+ try:
+ page_ranges = self._clients.page_blob.get_page_ranges()
+ self._non_empty_ranges = get_page_ranges_result(page_ranges)[0]
+ # according to the REST API documentation:
+ # in a highly fragmented page blob with a large number of writes,
+ # a Get Page Ranges request can fail due to an internal server timeout.
+ # thus, if the page blob is not sparse, it's ok for it to fail
+ except HttpResponseError:
+ pass
+
+ # If the file is small, the download is complete at this point.
+ # If file size is large, download the rest of the file in chunks.
+ if response.properties.size != self.size:
+ if self._request_options.get("modified_access_conditions"):
+ self._request_options["modified_access_conditions"].if_match = response.properties.etag
+ else:
+ self._download_complete = True
+ return response
+
+ def chunks(self):
+ # type: () -> Iterator[bytes]
+ """Iterate over chunks in the download stream.
+
+ :rtype: Iterator[bytes]
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_hello_world.py
+ :start-after: [START download_a_blob_in_chunk]
+ :end-before: [END download_a_blob_in_chunk]
+ :language: python
+ :dedent: 12
+ :caption: Download a blob using chunks().
+ """
+ if self.size == 0 or self._download_complete:
+ iter_downloader = None
+ else:
+ data_end = self._file_size
+ if self._end_range is not None:
+ # Use the end range index unless it is over the end of the file
+ data_end = min(self._file_size, self._end_range + 1)
+ iter_downloader = _ChunkDownloader(
+ client=self._clients.blob,
+ non_empty_ranges=self._non_empty_ranges,
+ total_size=self.size,
+ chunk_size=self._config.max_chunk_get_size,
+ current_progress=self._first_get_size,
+ start_range=self._initial_range[1] + 1, # start where the first download ended
+ end_range=data_end,
+ stream=None,
+ parallel=False,
+ validate_content=self._validate_content,
+ encryption_options=self._encryption_options,
+ use_location=self._location_mode,
+ **self._request_options
+ )
+ return _ChunkIterator(
+ size=self.size,
+ content=self._current_content,
+ downloader=iter_downloader,
+ chunk_size=self._config.max_chunk_get_size)
+
+ def readall(self):
+ # type: () -> Union[bytes, str]
+ """Download the contents of this blob.
+
+ This operation is blocking until all data is downloaded.
+
+ :rtype: bytes or str
+ """
+ stream = BytesIO()
+ self.readinto(stream)
+ data = stream.getvalue()
+ if self._encoding:
+ return data.decode(self._encoding)
+ return data
+
+ def content_as_bytes(self, max_concurrency=1):
+ """Download the contents of this file.
+
+ This operation is blocking until all data is downloaded.
+
+ :keyword int max_concurrency:
+ The number of parallel connections with which to download.
+ :rtype: bytes
+ """
+ warnings.warn(
+ "content_as_bytes is deprecated, use readall instead",
+ DeprecationWarning
+ )
+ self._max_concurrency = max_concurrency
+ return self.readall()
+
+ def content_as_text(self, max_concurrency=1, encoding="UTF-8"):
+ """Download the contents of this blob, and decode as text.
+
+ This operation is blocking until all data is downloaded.
+
+ :keyword int max_concurrency:
+ The number of parallel connections with which to download.
+ :param str encoding:
+ Test encoding to decode the downloaded bytes. Default is UTF-8.
+ :rtype: str
+ """
+ warnings.warn(
+ "content_as_text is deprecated, use readall instead",
+ DeprecationWarning
+ )
+ self._max_concurrency = max_concurrency
+ self._encoding = encoding
+ return self.readall()
+
+ def readinto(self, stream):
+ """Download the contents of this file to a stream.
+
+ :param stream:
+ The stream to download to. This can be an open file-handle,
+ or any writable stream. The stream must be seekable if the download
+ uses more than one parallel connection.
+ :returns: The number of bytes read.
+ :rtype: int
+ """
+ # The stream must be seekable if parallel download is required
+ parallel = self._max_concurrency > 1
+ if parallel:
+ error_message = "Target stream handle must be seekable."
+ if sys.version_info >= (3,) and not stream.seekable():
+ raise ValueError(error_message)
+
+ try:
+ stream.seek(stream.tell())
+ except (NotImplementedError, AttributeError):
+ raise ValueError(error_message)
+
+ # Write the content to the user stream
+ stream.write(self._current_content)
+ if self._download_complete:
+ return self.size
+
+ data_end = self._file_size
+ if self._end_range is not None:
+ # Use the length unless it is over the end of the file
+ data_end = min(self._file_size, self._end_range + 1)
+
+ downloader = _ChunkDownloader(
+ client=self._clients.blob,
+ non_empty_ranges=self._non_empty_ranges,
+ total_size=self.size,
+ chunk_size=self._config.max_chunk_get_size,
+ current_progress=self._first_get_size,
+ start_range=self._initial_range[1] + 1, # Start where the first download ended
+ end_range=data_end,
+ stream=stream,
+ parallel=parallel,
+ validate_content=self._validate_content,
+ encryption_options=self._encryption_options,
+ use_location=self._location_mode,
+ **self._request_options
+ )
+ if parallel:
+ import concurrent.futures
+ with concurrent.futures.ThreadPoolExecutor(self._max_concurrency) as executor:
+ list(executor.map(
+ with_current_context(downloader.process_chunk),
+ downloader.get_chunk_offsets()
+ ))
+ else:
+ for chunk in downloader.get_chunk_offsets():
+ downloader.process_chunk(chunk)
+ return self.size
+
+ def download_to_stream(self, stream, max_concurrency=1):
+ """Download the contents of this blob to a stream.
+
+ :param stream:
+ The stream to download to. This can be an open file-handle,
+ or any writable stream. The stream must be seekable if the download
+ uses more than one parallel connection.
+ :returns: The properties of the downloaded blob.
+ :rtype: Any
+ """
+ warnings.warn(
+ "download_to_stream is deprecated, use readinto instead",
+ DeprecationWarning
+ )
+ self._max_concurrency = max_concurrency
+ self.readinto(stream)
+ return self.properties
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/__init__.py
new file mode 100644
index 00000000000..cc760e7efd2
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/__init__.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from ._azure_blob_storage import AzureBlobStorage
+__all__ = ['AzureBlobStorage']
+
+try:
+ from ._patch import patch_sdk # type: ignore
+ patch_sdk()
+except ImportError:
+ pass
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/_azure_blob_storage.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/_azure_blob_storage.py
new file mode 100644
index 00000000000..578f65816c0
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/_azure_blob_storage.py
@@ -0,0 +1,106 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from typing import TYPE_CHECKING
+
+from azure.core import PipelineClient
+from msrest import Deserializer, Serializer
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import,ungrouped-imports
+ from typing import Any
+
+ from azure.core.pipeline.transport import HttpRequest, HttpResponse
+
+from ._configuration import AzureBlobStorageConfiguration
+from .operations import ServiceOperations
+from .operations import ContainerOperations
+from .operations import BlobOperations
+from .operations import PageBlobOperations
+from .operations import AppendBlobOperations
+from .operations import BlockBlobOperations
+from . import models
+
+
+class AzureBlobStorage(object):
+ """AzureBlobStorage.
+
+ :ivar service: ServiceOperations operations
+ :vartype service: azure.storage.blob.operations.ServiceOperations
+ :ivar container: ContainerOperations operations
+ :vartype container: azure.storage.blob.operations.ContainerOperations
+ :ivar blob: BlobOperations operations
+ :vartype blob: azure.storage.blob.operations.BlobOperations
+ :ivar page_blob: PageBlobOperations operations
+ :vartype page_blob: azure.storage.blob.operations.PageBlobOperations
+ :ivar append_blob: AppendBlobOperations operations
+ :vartype append_blob: azure.storage.blob.operations.AppendBlobOperations
+ :ivar block_blob: BlockBlobOperations operations
+ :vartype block_blob: azure.storage.blob.operations.BlockBlobOperations
+ :param url: The URL of the service account, container, or blob that is the target of the desired operation.
+ :type url: str
+ """
+
+ def __init__(
+ self,
+ url, # type: str
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ base_url = '{url}'
+ self._config = AzureBlobStorageConfiguration(url, **kwargs)
+ self._client = PipelineClient(base_url=base_url, config=self._config, **kwargs)
+
+ client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
+ self._serialize = Serializer(client_models)
+ self._serialize.client_side_validation = False
+ self._deserialize = Deserializer(client_models)
+
+ self.service = ServiceOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.container = ContainerOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.blob = BlobOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.page_blob = PageBlobOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.append_blob = AppendBlobOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.block_blob = BlockBlobOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+
+ def _send_request(self, http_request, **kwargs):
+ # type: (HttpRequest, Any) -> HttpResponse
+ """Runs the network request through the client's chained policies.
+
+ :param http_request: The network request you want to make. Required.
+ :type http_request: ~azure.core.pipeline.transport.HttpRequest
+ :keyword bool stream: Whether the response payload will be streamed. Defaults to True.
+ :return: The response of your network call. Does not do error handling on your response.
+ :rtype: ~azure.core.pipeline.transport.HttpResponse
+ """
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ http_request.url = self._client.format_url(http_request.url, **path_format_arguments)
+ stream = kwargs.pop("stream", True)
+ pipeline_response = self._client._pipeline.run(http_request, stream=stream, **kwargs)
+ return pipeline_response.http_response
+
+ def close(self):
+ # type: () -> None
+ self._client.close()
+
+ def __enter__(self):
+ # type: () -> AzureBlobStorage
+ self._client.__enter__()
+ return self
+
+ def __exit__(self, *exc_details):
+ # type: (Any) -> None
+ self._client.__exit__(*exc_details)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/_configuration.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/_configuration.py
new file mode 100644
index 00000000000..e25c0cdfe7d
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/_configuration.py
@@ -0,0 +1,58 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from typing import TYPE_CHECKING
+
+from azure.core.configuration import Configuration
+from azure.core.pipeline import policies
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import,ungrouped-imports
+ from typing import Any
+
+VERSION = "unknown"
+
+class AzureBlobStorageConfiguration(Configuration):
+ """Configuration for AzureBlobStorage.
+
+ Note that all parameters used to create this instance are saved as instance
+ attributes.
+
+ :param url: The URL of the service account, container, or blob that is the target of the desired operation.
+ :type url: str
+ """
+
+ def __init__(
+ self,
+ url, # type: str
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ if url is None:
+ raise ValueError("Parameter 'url' must not be None.")
+ super(AzureBlobStorageConfiguration, self).__init__(**kwargs)
+
+ self.url = url
+ self.version = "2021-04-10"
+ kwargs.setdefault('sdk_moniker', 'azureblobstorage/{}'.format(VERSION))
+ self._configure(**kwargs)
+
+ def _configure(
+ self,
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs)
+ self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs)
+ self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs)
+ self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs)
+ self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs)
+ self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs)
+ self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs)
+ self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs)
+ self.authentication_policy = kwargs.get('authentication_policy')
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/__init__.py
new file mode 100644
index 00000000000..12cfcf636c4
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/__init__.py
@@ -0,0 +1,10 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from ._azure_blob_storage import AzureBlobStorage
+__all__ = ['AzureBlobStorage']
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/_azure_blob_storage.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/_azure_blob_storage.py
new file mode 100644
index 00000000000..68f116aaaa9
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/_azure_blob_storage.py
@@ -0,0 +1,96 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from typing import Any
+
+from azure.core import AsyncPipelineClient
+from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest
+from msrest import Deserializer, Serializer
+
+from ._configuration import AzureBlobStorageConfiguration
+from .operations import ServiceOperations
+from .operations import ContainerOperations
+from .operations import BlobOperations
+from .operations import PageBlobOperations
+from .operations import AppendBlobOperations
+from .operations import BlockBlobOperations
+from .. import models
+
+
+class AzureBlobStorage(object):
+ """AzureBlobStorage.
+
+ :ivar service: ServiceOperations operations
+ :vartype service: azure.storage.blob.aio.operations.ServiceOperations
+ :ivar container: ContainerOperations operations
+ :vartype container: azure.storage.blob.aio.operations.ContainerOperations
+ :ivar blob: BlobOperations operations
+ :vartype blob: azure.storage.blob.aio.operations.BlobOperations
+ :ivar page_blob: PageBlobOperations operations
+ :vartype page_blob: azure.storage.blob.aio.operations.PageBlobOperations
+ :ivar append_blob: AppendBlobOperations operations
+ :vartype append_blob: azure.storage.blob.aio.operations.AppendBlobOperations
+ :ivar block_blob: BlockBlobOperations operations
+ :vartype block_blob: azure.storage.blob.aio.operations.BlockBlobOperations
+ :param url: The URL of the service account, container, or blob that is the target of the desired operation.
+ :type url: str
+ """
+
+ def __init__(
+ self,
+ url: str,
+ **kwargs: Any
+ ) -> None:
+ base_url = '{url}'
+ self._config = AzureBlobStorageConfiguration(url, **kwargs)
+ self._client = AsyncPipelineClient(base_url=base_url, config=self._config, **kwargs)
+
+ client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
+ self._serialize = Serializer(client_models)
+ self._serialize.client_side_validation = False
+ self._deserialize = Deserializer(client_models)
+
+ self.service = ServiceOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.container = ContainerOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.blob = BlobOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.page_blob = PageBlobOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.append_blob = AppendBlobOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+ self.block_blob = BlockBlobOperations(
+ self._client, self._config, self._serialize, self._deserialize)
+
+ async def _send_request(self, http_request: HttpRequest, **kwargs: Any) -> AsyncHttpResponse:
+ """Runs the network request through the client's chained policies.
+
+ :param http_request: The network request you want to make. Required.
+ :type http_request: ~azure.core.pipeline.transport.HttpRequest
+ :keyword bool stream: Whether the response payload will be streamed. Defaults to True.
+ :return: The response of your network call. Does not do error handling on your response.
+ :rtype: ~azure.core.pipeline.transport.AsyncHttpResponse
+ """
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ http_request.url = self._client.format_url(http_request.url, **path_format_arguments)
+ stream = kwargs.pop("stream", True)
+ pipeline_response = await self._client._pipeline.run(http_request, stream=stream, **kwargs)
+ return pipeline_response.http_response
+
+ async def close(self) -> None:
+ await self._client.close()
+
+ async def __aenter__(self) -> "AzureBlobStorage":
+ await self._client.__aenter__()
+ return self
+
+ async def __aexit__(self, *exc_details) -> None:
+ await self._client.__aexit__(*exc_details)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/_configuration.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/_configuration.py
new file mode 100644
index 00000000000..bcf04ce4a72
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/_configuration.py
@@ -0,0 +1,52 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from typing import Any
+
+from azure.core.configuration import Configuration
+from azure.core.pipeline import policies
+
+VERSION = "unknown"
+
+class AzureBlobStorageConfiguration(Configuration):
+ """Configuration for AzureBlobStorage.
+
+ Note that all parameters used to create this instance are saved as instance
+ attributes.
+
+ :param url: The URL of the service account, container, or blob that is the target of the desired operation.
+ :type url: str
+ """
+
+ def __init__(
+ self,
+ url: str,
+ **kwargs: Any
+ ) -> None:
+ if url is None:
+ raise ValueError("Parameter 'url' must not be None.")
+ super(AzureBlobStorageConfiguration, self).__init__(**kwargs)
+
+ self.url = url
+ self.version = "2021-04-10"
+ kwargs.setdefault('sdk_moniker', 'azureblobstorage/{}'.format(VERSION))
+ self._configure(**kwargs)
+
+ def _configure(
+ self,
+ **kwargs: Any
+ ) -> None:
+ self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs)
+ self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs)
+ self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs)
+ self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs)
+ self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs)
+ self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs)
+ self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs)
+ self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs)
+ self.authentication_policy = kwargs.get('authentication_policy')
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/__init__.py
new file mode 100644
index 00000000000..902269d05ed
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/__init__.py
@@ -0,0 +1,23 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from ._service_operations import ServiceOperations
+from ._container_operations import ContainerOperations
+from ._blob_operations import BlobOperations
+from ._page_blob_operations import PageBlobOperations
+from ._append_blob_operations import AppendBlobOperations
+from ._block_blob_operations import BlockBlobOperations
+
+__all__ = [
+ 'ServiceOperations',
+ 'ContainerOperations',
+ 'BlobOperations',
+ 'PageBlobOperations',
+ 'AppendBlobOperations',
+ 'BlockBlobOperations',
+]
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_append_blob_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_append_blob_operations.py
new file mode 100644
index 00000000000..4d18668ce67
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_append_blob_operations.py
@@ -0,0 +1,726 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest
+
+from ... import models as _models
+
+T = TypeVar('T')
+ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]]
+
+class AppendBlobOperations:
+ """AppendBlobOperations async operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer) -> None:
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ async def create(
+ self,
+ content_length: int,
+ timeout: Optional[int] = None,
+ metadata: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ blob_tags_string: Optional[str] = None,
+ immutability_policy_expiry: Optional[datetime.datetime] = None,
+ immutability_policy_mode: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]] = None,
+ legal_hold: Optional[bool] = None,
+ blob_http_headers: Optional["_models.BlobHTTPHeaders"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Create Append Blob operation creates a new append blob.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _blob_cache_control = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if blob_http_headers is not None:
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ blob_type = "AppendBlob"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.create.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ create.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def append_block(
+ self,
+ content_length: int,
+ body: IO,
+ timeout: Optional[int] = None,
+ transactional_content_md5: Optional[bytearray] = None,
+ transactional_content_crc64: Optional[bytearray] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ append_position_access_conditions: Optional["_models.AppendPositionAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Append Block operation commits a new block of data to the end of an existing append blob.
+ The Append Block operation is permitted only if the blob was created with x-ms-blob-type set to
+ AppendBlob. Append Block is supported only on version 2015-02-21 version or later.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param body: Initial data.
+ :type body: IO
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param append_position_access_conditions: Parameter group.
+ :type append_position_access_conditions: ~azure.storage.blob.models.AppendPositionAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _max_size = None
+ _append_position = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if append_position_access_conditions is not None:
+ _max_size = append_position_access_conditions.max_size
+ _append_position = append_position_access_conditions.append_position
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "appendblock"
+ content_type = kwargs.pop("content_type", "application/octet-stream")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.append_block.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _max_size is not None:
+ header_parameters['x-ms-blob-condition-maxsize'] = self._serialize.header("max_size", _max_size, 'long')
+ if _append_position is not None:
+ header_parameters['x-ms-blob-condition-appendpos'] = self._serialize.header("append_position", _append_position, 'long')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content_kwargs['stream_content'] = body
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-append-offset']=self._deserialize('str', response.headers.get('x-ms-blob-append-offset'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ append_block.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def append_block_from_url(
+ self,
+ source_url: str,
+ content_length: int,
+ source_range: Optional[str] = None,
+ source_content_md5: Optional[bytearray] = None,
+ source_contentcrc64: Optional[bytearray] = None,
+ timeout: Optional[int] = None,
+ transactional_content_md5: Optional[bytearray] = None,
+ request_id_parameter: Optional[str] = None,
+ copy_source_authorization: Optional[str] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ append_position_access_conditions: Optional["_models.AppendPositionAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ source_modified_access_conditions: Optional["_models.SourceModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Append Block operation commits a new block of data to the end of an existing append blob
+ where the contents are read from a source url. The Append Block operation is permitted only if
+ the blob was created with x-ms-blob-type set to AppendBlob. Append Block is supported only on
+ version 2015-02-21 version or later.
+
+ :param source_url: Specify a URL to the copy source.
+ :type source_url: str
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param source_range: Bytes of source data in the specified range.
+ :type source_range: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param source_contentcrc64: Specify the crc64 calculated for the range of bytes that must be
+ read from the copy source.
+ :type source_contentcrc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param append_position_access_conditions: Parameter group.
+ :type append_position_access_conditions: ~azure.storage.blob.models.AppendPositionAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _lease_id = None
+ _max_size = None
+ _append_position = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ if append_position_access_conditions is not None:
+ _max_size = append_position_access_conditions.max_size
+ _append_position = append_position_access_conditions.append_position
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ comp = "appendblock"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.append_block_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-copy-source'] = self._serialize.header("source_url", source_url, 'str')
+ if source_range is not None:
+ header_parameters['x-ms-source-range'] = self._serialize.header("source_range", source_range, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if source_contentcrc64 is not None:
+ header_parameters['x-ms-source-content-crc64'] = self._serialize.header("source_contentcrc64", source_contentcrc64, 'bytearray')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _max_size is not None:
+ header_parameters['x-ms-blob-condition-maxsize'] = self._serialize.header("max_size", _max_size, 'long')
+ if _append_position is not None:
+ header_parameters['x-ms-blob-condition-appendpos'] = self._serialize.header("append_position", _append_position, 'long')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-append-offset']=self._deserialize('str', response.headers.get('x-ms-blob-append-offset'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ append_block_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def seal(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ append_position_access_conditions: Optional["_models.AppendPositionAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Seal operation seals the Append Blob to make it read-only. Seal is supported only on
+ version 2019-12-12 version or later.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param append_position_access_conditions: Parameter group.
+ :type append_position_access_conditions: ~azure.storage.blob.models.AppendPositionAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _append_position = None
+ if append_position_access_conditions is not None:
+ _append_position = append_position_access_conditions.append_position
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ comp = "seal"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.seal.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _append_position is not None:
+ header_parameters['x-ms-blob-condition-appendpos'] = self._serialize.header("append_position", _append_position, 'long')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-sealed']=self._deserialize('bool', response.headers.get('x-ms-blob-sealed'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ seal.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_blob_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_blob_operations.py
new file mode 100644
index 00000000000..46a5ad21ca3
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_blob_operations.py
@@ -0,0 +1,3008 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest
+
+from ... import models as _models
+
+T = TypeVar('T')
+ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]]
+
+class BlobOperations:
+ """BlobOperations async operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer) -> None:
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ async def download(
+ self,
+ snapshot: Optional[str] = None,
+ version_id: Optional[str] = None,
+ timeout: Optional[int] = None,
+ range: Optional[str] = None,
+ range_get_content_md5: Optional[bool] = None,
+ range_get_content_crc64: Optional[bool] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> IO:
+ """The Download operation reads or downloads a blob from the system, including its metadata and
+ properties. You can also call Download to read a snapshot.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param range_get_content_md5: When set to true and specified together with the Range, the
+ service returns the MD5 hash for the range, as long as the range is less than or equal to 4 MB
+ in size.
+ :type range_get_content_md5: bool
+ :param range_get_content_crc64: When set to true and specified together with the Range, the
+ service returns the CRC64 hash for the range, as long as the range is less than or equal to 4
+ MB in size.
+ :type range_get_content_crc64: bool
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: IO, or the result of cls(response)
+ :rtype: IO
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[IO]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.download.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if range_get_content_md5 is not None:
+ header_parameters['x-ms-range-get-content-md5'] = self._serialize.header("range_get_content_md5", range_get_content_md5, 'bool')
+ if range_get_content_crc64 is not None:
+ header_parameters['x-ms-range-get-content-crc64'] = self._serialize.header("range_get_content_crc64", range_get_content_crc64, 'bool')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=True, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200, 206]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ if response.status_code == 200:
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['x-ms-or-policy-id']=self._deserialize('str', response.headers.get('x-ms-or-policy-id'))
+ response_headers['x-ms-or']=self._deserialize('str', response.headers.get('x-ms-or'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['Content-Range']=self._deserialize('str', response.headers.get('Content-Range'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['x-ms-is-current-version']=self._deserialize('bool', response.headers.get('x-ms-is-current-version'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-blob-content-md5']=self._deserialize('bytearray', response.headers.get('x-ms-blob-content-md5'))
+ response_headers['x-ms-tag-count']=self._deserialize('long', response.headers.get('x-ms-tag-count'))
+ response_headers['x-ms-blob-sealed']=self._deserialize('bool', response.headers.get('x-ms-blob-sealed'))
+ response_headers['x-ms-last-access-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-last-access-time'))
+ response_headers['x-ms-immutability-policy-until-date']=self._deserialize('rfc-1123', response.headers.get('x-ms-immutability-policy-until-date'))
+ response_headers['x-ms-immutability-policy-mode']=self._deserialize('str', response.headers.get('x-ms-immutability-policy-mode'))
+ response_headers['x-ms-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-legal-hold'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if response.status_code == 206:
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['x-ms-or-policy-id']=self._deserialize('str', response.headers.get('x-ms-or-policy-id'))
+ response_headers['x-ms-or']=self._deserialize('str', response.headers.get('x-ms-or'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['Content-Range']=self._deserialize('str', response.headers.get('Content-Range'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['x-ms-is-current-version']=self._deserialize('bool', response.headers.get('x-ms-is-current-version'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-blob-content-md5']=self._deserialize('bytearray', response.headers.get('x-ms-blob-content-md5'))
+ response_headers['x-ms-tag-count']=self._deserialize('long', response.headers.get('x-ms-tag-count'))
+ response_headers['x-ms-blob-sealed']=self._deserialize('bool', response.headers.get('x-ms-blob-sealed'))
+ response_headers['x-ms-last-access-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-last-access-time'))
+ response_headers['x-ms-immutability-policy-until-date']=self._deserialize('rfc-1123', response.headers.get('x-ms-immutability-policy-until-date'))
+ response_headers['x-ms-immutability-policy-mode']=self._deserialize('str', response.headers.get('x-ms-immutability-policy-mode'))
+ response_headers['x-ms-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-legal-hold'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ download.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def get_properties(
+ self,
+ snapshot: Optional[str] = None,
+ version_id: Optional[str] = None,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Get Properties operation returns all user-defined metadata, standard HTTP properties, and
+ system properties for the blob. It does not return the content of the blob.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_properties.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.head(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-creation-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-creation-time'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['x-ms-or-policy-id']=self._deserialize('str', response.headers.get('x-ms-or-policy-id'))
+ response_headers['x-ms-or']=self._deserialize('str', response.headers.get('x-ms-or'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-incremental-copy']=self._deserialize('bool', response.headers.get('x-ms-incremental-copy'))
+ response_headers['x-ms-copy-destination-snapshot']=self._deserialize('str', response.headers.get('x-ms-copy-destination-snapshot'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-access-tier']=self._deserialize('str', response.headers.get('x-ms-access-tier'))
+ response_headers['x-ms-access-tier-inferred']=self._deserialize('bool', response.headers.get('x-ms-access-tier-inferred'))
+ response_headers['x-ms-archive-status']=self._deserialize('str', response.headers.get('x-ms-archive-status'))
+ response_headers['x-ms-access-tier-change-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-access-tier-change-time'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['x-ms-is-current-version']=self._deserialize('bool', response.headers.get('x-ms-is-current-version'))
+ response_headers['x-ms-tag-count']=self._deserialize('long', response.headers.get('x-ms-tag-count'))
+ response_headers['x-ms-expiry-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-expiry-time'))
+ response_headers['x-ms-blob-sealed']=self._deserialize('bool', response.headers.get('x-ms-blob-sealed'))
+ response_headers['x-ms-rehydrate-priority']=self._deserialize('str', response.headers.get('x-ms-rehydrate-priority'))
+ response_headers['x-ms-last-access-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-last-access-time'))
+ response_headers['x-ms-immutability-policy-until-date']=self._deserialize('rfc-1123', response.headers.get('x-ms-immutability-policy-until-date'))
+ response_headers['x-ms-immutability-policy-mode']=self._deserialize('str', response.headers.get('x-ms-immutability-policy-mode'))
+ response_headers['x-ms-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-legal-hold'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_properties.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def delete(
+ self,
+ snapshot: Optional[str] = None,
+ version_id: Optional[str] = None,
+ timeout: Optional[int] = None,
+ delete_snapshots: Optional[Union[str, "_models.DeleteSnapshotsOptionType"]] = None,
+ request_id_parameter: Optional[str] = None,
+ blob_delete_type: Optional[str] = "Permanent",
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """If the storage account's soft delete feature is disabled then, when a blob is deleted, it is
+ permanently removed from the storage account. If the storage account's soft delete feature is
+ enabled, then, when a blob is deleted, it is marked for deletion and becomes inaccessible
+ immediately. However, the blob service retains the blob or snapshot for the number of days
+ specified by the DeleteRetentionPolicy section of [Storage service properties]
+ (Set-Blob-Service-Properties.md). After the specified number of days has passed, the blob's
+ data is permanently removed from the storage account. Note that you continue to be charged for
+ the soft-deleted blob's storage until it is permanently removed. Use the List Blobs API and
+ specify the "include=deleted" query parameter to discover which blobs and snapshots have been
+ soft deleted. You can then use the Undelete Blob API to restore a soft-deleted blob. All other
+ operations on a soft-deleted blob or snapshot causes the service to return an HTTP status code
+ of 404 (ResourceNotFound).
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param delete_snapshots: Required if the blob has associated snapshots. Specify one of the
+ following two options: include: Delete the base blob and all of its snapshots. only: Delete
+ only the blob's snapshots and not the blob itself.
+ :type delete_snapshots: str or ~azure.storage.blob.models.DeleteSnapshotsOptionType
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_delete_type: Optional. Only possible value is 'permanent', which specifies to
+ permanently delete a blob if blob soft delete is enabled.
+ :type blob_delete_type: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.delete.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if blob_delete_type is not None:
+ query_parameters['deletetype'] = self._serialize.query("blob_delete_type", blob_delete_type, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if delete_snapshots is not None:
+ header_parameters['x-ms-delete-snapshots'] = self._serialize.header("delete_snapshots", delete_snapshots, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.delete(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ delete.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def undelete(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> None:
+ """Undelete a blob that was previously soft deleted.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "undelete"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.undelete.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ undelete.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def set_expiry(
+ self,
+ expiry_options: Union[str, "_models.BlobExpiryOptions"],
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ expires_on: Optional[str] = None,
+ **kwargs: Any
+ ) -> None:
+ """Sets the time a blob will expire and be deleted.
+
+ :param expiry_options: Required. Indicates mode of the expiry time.
+ :type expiry_options: str or ~azure.storage.blob.models.BlobExpiryOptions
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param expires_on: The time to set the blob to expiry.
+ :type expires_on: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "expiry"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_expiry.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['x-ms-expiry-option'] = self._serialize.header("expiry_options", expiry_options, 'str')
+ if expires_on is not None:
+ header_parameters['x-ms-expiry-time'] = self._serialize.header("expires_on", expires_on, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_expiry.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def set_http_headers(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ blob_http_headers: Optional["_models.BlobHTTPHeaders"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Set HTTP Headers operation sets system properties on the blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_cache_control = None
+ _blob_content_type = None
+ _blob_content_md5 = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _blob_content_disposition = None
+ if blob_http_headers is not None:
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_http_headers.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_http_headers.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def set_immutability_policy(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ immutability_policy_expiry: Optional[datetime.datetime] = None,
+ immutability_policy_mode: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Set Immutability Policy operation sets the immutability policy on the blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "immutabilityPolicies"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_immutability_policy.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-immutability-policy-until-date']=self._deserialize('rfc-1123', response.headers.get('x-ms-immutability-policy-until-date'))
+ response_headers['x-ms-immutability-policy-mode']=self._deserialize('str', response.headers.get('x-ms-immutability-policy-mode'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_immutability_policy.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def delete_immutability_policy(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Delete Immutability Policy operation deletes the immutability policy on the blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "immutabilityPolicies"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.delete_immutability_policy.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.delete(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ delete_immutability_policy.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def set_legal_hold(
+ self,
+ legal_hold: bool,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Set Legal Hold operation sets a legal hold on the blob.
+
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "legalhold"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_legal_hold.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-legal-hold'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_legal_hold.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def set_metadata(
+ self,
+ timeout: Optional[int] = None,
+ metadata: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Set Blob Metadata operation sets user-defined metadata for the specified blob as one or
+ more name-value pairs.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "metadata"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_metadata.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_metadata.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def acquire_lease(
+ self,
+ timeout: Optional[int] = None,
+ duration: Optional[int] = None,
+ proposed_lease_id: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param duration: Specifies the duration of the lease, in seconds, or negative one (-1) for a
+ lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease
+ duration cannot be changed using renew or change.
+ :type duration: int
+ :param proposed_lease_id: Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid
+ Constructor (String) for a list of valid GUID string formats.
+ :type proposed_lease_id: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "acquire"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.acquire_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ if duration is not None:
+ header_parameters['x-ms-lease-duration'] = self._serialize.header("duration", duration, 'int')
+ if proposed_lease_id is not None:
+ header_parameters['x-ms-proposed-lease-id'] = self._serialize.header("proposed_lease_id", proposed_lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ acquire_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def release_lease(
+ self,
+ lease_id: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "release"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.release_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ release_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def renew_lease(
+ self,
+ lease_id: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "renew"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.renew_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ renew_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def change_lease(
+ self,
+ lease_id: str,
+ proposed_lease_id: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param proposed_lease_id: Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid
+ Constructor (String) for a list of valid GUID string formats.
+ :type proposed_lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "change"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.change_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ header_parameters['x-ms-proposed-lease-id'] = self._serialize.header("proposed_lease_id", proposed_lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ change_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def break_lease(
+ self,
+ timeout: Optional[int] = None,
+ break_period: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param break_period: For a break operation, proposed duration the lease should continue before
+ it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter
+ than the time remaining on the lease. If longer, the time remaining on the lease is used. A new
+ lease will not be available before the break period has expired, but the lease may be held for
+ longer than the break period. If this header does not appear with a break operation, a
+ fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease
+ breaks immediately.
+ :type break_period: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "break"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.break_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ if break_period is not None:
+ header_parameters['x-ms-lease-break-period'] = self._serialize.header("break_period", break_period, 'int')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-time']=self._deserialize('int', response.headers.get('x-ms-lease-time'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ break_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def create_snapshot(
+ self,
+ timeout: Optional[int] = None,
+ metadata: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Create Snapshot operation creates a read-only snapshot of a blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _lease_id = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "snapshot"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.create_snapshot.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-snapshot']=self._deserialize('str', response.headers.get('x-ms-snapshot'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ create_snapshot.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def start_copy_from_url(
+ self,
+ copy_source: str,
+ timeout: Optional[int] = None,
+ metadata: Optional[str] = None,
+ tier: Optional[Union[str, "_models.AccessTierOptional"]] = None,
+ rehydrate_priority: Optional[Union[str, "_models.RehydratePriority"]] = None,
+ request_id_parameter: Optional[str] = None,
+ blob_tags_string: Optional[str] = None,
+ seal_blob: Optional[bool] = None,
+ immutability_policy_expiry: Optional[datetime.datetime] = None,
+ immutability_policy_mode: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]] = None,
+ legal_hold: Optional[bool] = None,
+ source_modified_access_conditions: Optional["_models.SourceModifiedAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Start Copy From URL operation copies a blob or an internet resource to a new blob.
+
+ :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
+ up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
+ would appear in a request URI. The source blob must either be public or must be authenticated
+ via a shared access signature.
+ :type copy_source: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param rehydrate_priority: Optional: Indicates the priority with which to rehydrate an archived
+ blob.
+ :type rehydrate_priority: str or ~azure.storage.blob.models.RehydratePriority
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param seal_blob: Overrides the sealed state of the destination blob. Service version
+ 2019-12-12 and newer.
+ :type seal_blob: bool
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ _source_if_tags = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ _source_if_tags = source_modified_access_conditions.source_if_tags
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.start_copy_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if rehydrate_priority is not None:
+ header_parameters['x-ms-rehydrate-priority'] = self._serialize.header("rehydrate_priority", rehydrate_priority, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ if _source_if_tags is not None:
+ header_parameters['x-ms-source-if-tags'] = self._serialize.header("source_if_tags", _source_if_tags, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if seal_blob is not None:
+ header_parameters['x-ms-seal-blob'] = self._serialize.header("seal_blob", seal_blob, 'bool')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ start_copy_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def copy_from_url(
+ self,
+ copy_source: str,
+ timeout: Optional[int] = None,
+ metadata: Optional[str] = None,
+ tier: Optional[Union[str, "_models.AccessTierOptional"]] = None,
+ request_id_parameter: Optional[str] = None,
+ source_content_md5: Optional[bytearray] = None,
+ blob_tags_string: Optional[str] = None,
+ immutability_policy_expiry: Optional[datetime.datetime] = None,
+ immutability_policy_mode: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]] = None,
+ legal_hold: Optional[bool] = None,
+ copy_source_authorization: Optional[str] = None,
+ source_modified_access_conditions: Optional["_models.SourceModifiedAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Copy From URL operation copies a blob or an internet resource to a new blob. It will not
+ return a response until the copy is complete.
+
+ :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
+ up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
+ would appear in a request URI. The source blob must either be public or must be authenticated
+ via a shared access signature.
+ :type copy_source: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _lease_id = None
+ _encryption_scope = None
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ x_ms_requires_sync = "true"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.copy_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-requires-sync'] = self._serialize.header("x_ms_requires_sync", x_ms_requires_sync, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ copy_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def abort_copy_from_url(
+ self,
+ copy_id: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a
+ destination blob with zero length and full metadata.
+
+ :param copy_id: The copy identifier provided in the x-ms-copy-id header of the original Copy
+ Blob operation.
+ :type copy_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ comp = "copy"
+ copy_action_abort_constant = "abort"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.abort_copy_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['copyid'] = self._serialize.query("copy_id", copy_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-copy-action'] = self._serialize.header("copy_action_abort_constant", copy_action_abort_constant, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [204]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ abort_copy_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def set_tier(
+ self,
+ tier: Union[str, "_models.AccessTierRequired"],
+ snapshot: Optional[str] = None,
+ version_id: Optional[str] = None,
+ timeout: Optional[int] = None,
+ rehydrate_priority: Optional[Union[str, "_models.RehydratePriority"]] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Set Tier operation sets the tier on a blob. The operation is allowed on a page blob in a
+ premium storage account and on a block blob in a blob storage account (locally redundant
+ storage only). A premium page blob's tier determines the allowed size, IOPS, and bandwidth of
+ the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation does not
+ update the blob's ETag.
+
+ :param tier: Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierRequired
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param rehydrate_priority: Optional: Indicates the priority with which to rehydrate an archived
+ blob.
+ :type rehydrate_priority: str or ~azure.storage.blob.models.RehydratePriority
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_tags = modified_access_conditions.if_tags
+ comp = "tier"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_tier.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if rehydrate_priority is not None:
+ header_parameters['x-ms-rehydrate-priority'] = self._serialize.header("rehydrate_priority", rehydrate_priority, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200, 202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ if response.status_code == 200:
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+
+ if response.status_code == 202:
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_tier.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def get_account_info(
+ self,
+ **kwargs: Any
+ ) -> None:
+ """Returns the sku name and account kind.
+
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "account"
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_account_info.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-sku-name']=self._deserialize('str', response.headers.get('x-ms-sku-name'))
+ response_headers['x-ms-account-kind']=self._deserialize('str', response.headers.get('x-ms-account-kind'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_account_info.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def query(
+ self,
+ snapshot: Optional[str] = None,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ query_request: Optional["_models.QueryRequest"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> IO:
+ """The Query operation enables users to select/project on blob data by providing simple query
+ expressions.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param query_request: the query request.
+ :type query_request: ~azure.storage.blob.models.QueryRequest
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: IO, or the result of cls(response)
+ :rtype: IO
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[IO]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "query"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.query.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ if query_request is not None:
+ body_content = self._serialize.body(query_request, 'QueryRequest', is_xml=True)
+ else:
+ body_content = None
+ body_content_kwargs['content'] = body_content
+ request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=True, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200, 206]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ if response.status_code == 200:
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['Content-Range']=self._deserialize('str', response.headers.get('Content-Range'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-blob-content-md5']=self._deserialize('bytearray', response.headers.get('x-ms-blob-content-md5'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if response.status_code == 206:
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['Content-Range']=self._deserialize('str', response.headers.get('Content-Range'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-blob-content-md5']=self._deserialize('bytearray', response.headers.get('x-ms-blob-content-md5'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ query.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def get_tags(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ snapshot: Optional[str] = None,
+ version_id: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ **kwargs: Any
+ ) -> "_models.BlobTags":
+ """The Get Tags operation enables users to get the tags associated with a blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: BlobTags, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.BlobTags
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.BlobTags"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_tags = None
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_tags = modified_access_conditions.if_tags
+ comp = "tags"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_tags.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('BlobTags', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_tags.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def set_tags(
+ self,
+ timeout: Optional[int] = None,
+ version_id: Optional[str] = None,
+ transactional_content_md5: Optional[bytearray] = None,
+ transactional_content_crc64: Optional[bytearray] = None,
+ request_id_parameter: Optional[str] = None,
+ tags: Optional["_models.BlobTags"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Set Tags operation enables users to set tags on a blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param tags: Blob tags.
+ :type tags: ~azure.storage.blob.models.BlobTags
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_tags = None
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_tags = modified_access_conditions.if_tags
+ comp = "tags"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_tags.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ if tags is not None:
+ body_content = self._serialize.body(tags, 'BlobTags', is_xml=True)
+ else:
+ body_content = None
+ body_content_kwargs['content'] = body_content
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [204]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_tags.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_block_blob_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_block_blob_operations.py
new file mode 100644
index 00000000000..c45f674cb75
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_block_blob_operations.py
@@ -0,0 +1,1138 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest
+
+from ... import models as _models
+
+T = TypeVar('T')
+ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]]
+
+class BlockBlobOperations:
+ """BlockBlobOperations async operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer) -> None:
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ async def upload(
+ self,
+ content_length: int,
+ body: IO,
+ timeout: Optional[int] = None,
+ transactional_content_md5: Optional[bytearray] = None,
+ metadata: Optional[str] = None,
+ tier: Optional[Union[str, "_models.AccessTierOptional"]] = None,
+ request_id_parameter: Optional[str] = None,
+ blob_tags_string: Optional[str] = None,
+ immutability_policy_expiry: Optional[datetime.datetime] = None,
+ immutability_policy_mode: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]] = None,
+ legal_hold: Optional[bool] = None,
+ blob_http_headers: Optional["_models.BlobHTTPHeaders"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Upload Block Blob operation updates the content of an existing block blob. Updating an
+ existing block blob overwrites any existing metadata on the blob. Partial updates are not
+ supported with Put Blob; the content of the existing blob is overwritten with the content of
+ the new blob. To perform a partial update of the content of a block blob, use the Put Block
+ List operation.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param body: Initial data.
+ :type body: IO
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _blob_cache_control = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if blob_http_headers is not None:
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ blob_type = "BlockBlob"
+ content_type = kwargs.pop("content_type", "application/octet-stream")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.upload.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content_kwargs['stream_content'] = body
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ upload.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def put_blob_from_url(
+ self,
+ content_length: int,
+ copy_source: str,
+ timeout: Optional[int] = None,
+ transactional_content_md5: Optional[bytearray] = None,
+ metadata: Optional[str] = None,
+ tier: Optional[Union[str, "_models.AccessTierOptional"]] = None,
+ request_id_parameter: Optional[str] = None,
+ source_content_md5: Optional[bytearray] = None,
+ blob_tags_string: Optional[str] = None,
+ copy_source_blob_properties: Optional[bool] = None,
+ copy_source_authorization: Optional[str] = None,
+ blob_http_headers: Optional["_models.BlobHTTPHeaders"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ source_modified_access_conditions: Optional["_models.SourceModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Put Blob from URL operation creates a new Block Blob where the contents of the blob are
+ read from a given URL. This API is supported beginning with the 2020-04-08 version. Partial
+ updates are not supported with Put Blob from URL; the content of an existing blob is
+ overwritten with the content of the new blob. To perform partial updates to a block blob’s
+ contents using a source URL, use the Put Block from URL API in conjunction with Put Block List.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
+ up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
+ would appear in a request URI. The source blob must either be public or must be authenticated
+ via a shared access signature.
+ :type copy_source: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param copy_source_blob_properties: Optional, default is true. Indicates if properties from
+ the source blob should be copied.
+ :type copy_source_blob_properties: bool
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _blob_cache_control = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ _source_if_tags = None
+ if blob_http_headers is not None:
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ _source_if_tags = source_modified_access_conditions.source_if_tags
+ blob_type = "BlockBlob"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.put_blob_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ if _source_if_tags is not None:
+ header_parameters['x-ms-source-if-tags'] = self._serialize.header("source_if_tags", _source_if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
+ if copy_source_blob_properties is not None:
+ header_parameters['x-ms-copy-source-blob-properties'] = self._serialize.header("copy_source_blob_properties", copy_source_blob_properties, 'bool')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ put_blob_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def stage_block(
+ self,
+ block_id: str,
+ content_length: int,
+ body: IO,
+ transactional_content_md5: Optional[bytearray] = None,
+ transactional_content_crc64: Optional[bytearray] = None,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Stage Block operation creates a new block to be committed as part of a blob.
+
+ :param block_id: A valid Base64 string value that identifies the block. Prior to encoding, the
+ string must be less than or equal to 64 bytes in size. For a given blob, the length of the
+ value specified for the blockid parameter must be the same size for each block.
+ :type block_id: str
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param body: Initial data.
+ :type body: IO
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ comp = "block"
+ content_type = kwargs.pop("content_type", "application/octet-stream")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.stage_block.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['blockid'] = self._serialize.query("block_id", block_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content_kwargs['stream_content'] = body
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ stage_block.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def stage_block_from_url(
+ self,
+ block_id: str,
+ content_length: int,
+ source_url: str,
+ source_range: Optional[str] = None,
+ source_content_md5: Optional[bytearray] = None,
+ source_contentcrc64: Optional[bytearray] = None,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ copy_source_authorization: Optional[str] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ source_modified_access_conditions: Optional["_models.SourceModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Stage Block operation creates a new block to be committed as part of a blob where the
+ contents are read from a URL.
+
+ :param block_id: A valid Base64 string value that identifies the block. Prior to encoding, the
+ string must be less than or equal to 64 bytes in size. For a given blob, the length of the
+ value specified for the blockid parameter must be the same size for each block.
+ :type block_id: str
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param source_url: Specify a URL to the copy source.
+ :type source_url: str
+ :param source_range: Bytes of source data in the specified range.
+ :type source_range: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param source_contentcrc64: Specify the crc64 calculated for the range of bytes that must be
+ read from the copy source.
+ :type source_contentcrc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _lease_id = None
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ comp = "block"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.stage_block_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['blockid'] = self._serialize.query("block_id", block_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("source_url", source_url, 'str')
+ if source_range is not None:
+ header_parameters['x-ms-source-range'] = self._serialize.header("source_range", source_range, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if source_contentcrc64 is not None:
+ header_parameters['x-ms-source-content-crc64'] = self._serialize.header("source_contentcrc64", source_contentcrc64, 'bytearray')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ stage_block_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def commit_block_list(
+ self,
+ blocks: "_models.BlockLookupList",
+ timeout: Optional[int] = None,
+ transactional_content_md5: Optional[bytearray] = None,
+ transactional_content_crc64: Optional[bytearray] = None,
+ metadata: Optional[str] = None,
+ tier: Optional[Union[str, "_models.AccessTierOptional"]] = None,
+ request_id_parameter: Optional[str] = None,
+ blob_tags_string: Optional[str] = None,
+ immutability_policy_expiry: Optional[datetime.datetime] = None,
+ immutability_policy_mode: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]] = None,
+ legal_hold: Optional[bool] = None,
+ blob_http_headers: Optional["_models.BlobHTTPHeaders"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Commit Block List operation writes a blob by specifying the list of block IDs that make up
+ the blob. In order to be written as part of a blob, a block must have been successfully written
+ to the server in a prior Put Block operation. You can call Put Block List to update a blob by
+ uploading only those blocks that have changed, then committing the new and existing blocks
+ together. You can do this by specifying whether to commit a block from the committed block list
+ or from the uncommitted block list, or to commit the most recently uploaded version of the
+ block, whichever list it may belong to.
+
+ :param blocks: Blob Blocks.
+ :type blocks: ~azure.storage.blob.models.BlockLookupList
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_cache_control = None
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if blob_http_headers is not None:
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "blocklist"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.commit_block_list.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(blocks, 'BlockLookupList', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ commit_block_list.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def get_block_list(
+ self,
+ snapshot: Optional[str] = None,
+ list_type: Union[str, "_models.BlockListType"] = "committed",
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> "_models.BlockList":
+ """The Get Block List operation retrieves the list of blocks that have been uploaded as part of a
+ block blob.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param list_type: Specifies whether to return the list of committed blocks, the list of
+ uncommitted blocks, or both lists together.
+ :type list_type: str or ~azure.storage.blob.models.BlockListType
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: BlockList, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.BlockList
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.BlockList"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_tags = modified_access_conditions.if_tags
+ comp = "blocklist"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_block_list.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ query_parameters['blocklisttype'] = self._serialize.query("list_type", list_type, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-blob-content-length']=self._deserialize('long', response.headers.get('x-ms-blob-content-length'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('BlockList', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_block_list.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_container_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_container_operations.py
new file mode 100644
index 00000000000..18c70f533d8
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_container_operations.py
@@ -0,0 +1,1748 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import Any, Callable, Dict, Generic, IO, List, Optional, TypeVar, Union
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest
+
+from ... import models as _models
+
+T = TypeVar('T')
+ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]]
+
+class ContainerOperations:
+ """ContainerOperations async operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer) -> None:
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ async def create(
+ self,
+ timeout: Optional[int] = None,
+ metadata: Optional[str] = None,
+ access: Optional[Union[str, "_models.PublicAccessType"]] = None,
+ request_id_parameter: Optional[str] = None,
+ container_cpk_scope_info: Optional["_models.ContainerCpkScopeInfo"] = None,
+ **kwargs: Any
+ ) -> None:
+ """creates a new container under the specified account. If the container with the same name
+ already exists, the operation fails.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param access: Specifies whether data in the container may be accessed publicly and the level
+ of access.
+ :type access: str or ~azure.storage.blob.models.PublicAccessType
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param container_cpk_scope_info: Parameter group.
+ :type container_cpk_scope_info: ~azure.storage.blob.models.ContainerCpkScopeInfo
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _default_encryption_scope = None
+ _prevent_encryption_scope_override = None
+ if container_cpk_scope_info is not None:
+ _default_encryption_scope = container_cpk_scope_info.default_encryption_scope
+ _prevent_encryption_scope_override = container_cpk_scope_info.prevent_encryption_scope_override
+ restype = "container"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.create.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if access is not None:
+ header_parameters['x-ms-blob-public-access'] = self._serialize.header("access", access, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _default_encryption_scope is not None:
+ header_parameters['x-ms-default-encryption-scope'] = self._serialize.header("default_encryption_scope", _default_encryption_scope, 'str')
+ if _prevent_encryption_scope_override is not None:
+ header_parameters['x-ms-deny-encryption-scope-override'] = self._serialize.header("prevent_encryption_scope_override", _prevent_encryption_scope_override, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ create.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def get_properties(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """returns all user-defined metadata and system properties for the specified container. The data
+ returned does not include the container's list of blobs.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ restype = "container"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_properties.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-public-access']=self._deserialize('str', response.headers.get('x-ms-blob-public-access'))
+ response_headers['x-ms-has-immutability-policy']=self._deserialize('bool', response.headers.get('x-ms-has-immutability-policy'))
+ response_headers['x-ms-has-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-has-legal-hold'))
+ response_headers['x-ms-default-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-default-encryption-scope'))
+ response_headers['x-ms-deny-encryption-scope-override']=self._deserialize('bool', response.headers.get('x-ms-deny-encryption-scope-override'))
+ response_headers['x-ms-immutable-storage-with-versioning-enabled']=self._deserialize('bool', response.headers.get('x-ms-immutable-storage-with-versioning-enabled'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_properties.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def delete(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """operation marks the specified container for deletion. The container and any blobs contained
+ within it are later deleted during garbage collection.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ restype = "container"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.delete.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.delete(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ delete.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def set_metadata(
+ self,
+ timeout: Optional[int] = None,
+ metadata: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """operation sets one or more user-defined name-value pairs for the specified container.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ restype = "container"
+ comp = "metadata"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_metadata.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_metadata.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def get_access_policy(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ **kwargs: Any
+ ) -> List["_models.SignedIdentifier"]:
+ """gets the permissions for the specified container. The permissions indicate whether container
+ data may be accessed publicly.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: list of SignedIdentifier, or the result of cls(response)
+ :rtype: list[~azure.storage.blob.models.SignedIdentifier]
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[List["_models.SignedIdentifier"]]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ restype = "container"
+ comp = "acl"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_access_policy.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-blob-public-access']=self._deserialize('str', response.headers.get('x-ms-blob-public-access'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('[SignedIdentifier]', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_access_policy.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def set_access_policy(
+ self,
+ timeout: Optional[int] = None,
+ access: Optional[Union[str, "_models.PublicAccessType"]] = None,
+ request_id_parameter: Optional[str] = None,
+ container_acl: Optional[List["_models.SignedIdentifier"]] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """sets the permissions for the specified container. The permissions indicate whether blobs in a
+ container may be accessed publicly.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param access: Specifies whether data in the container may be accessed publicly and the level
+ of access.
+ :type access: str or ~azure.storage.blob.models.PublicAccessType
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param container_acl: the acls for the container.
+ :type container_acl: list[~azure.storage.blob.models.SignedIdentifier]
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ restype = "container"
+ comp = "acl"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_access_policy.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if access is not None:
+ header_parameters['x-ms-blob-public-access'] = self._serialize.header("access", access, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ serialization_ctxt = {'xml': {'name': 'SignedIdentifiers', 'wrapped': True, 'itemsName': 'SignedIdentifier'}}
+ if container_acl is not None:
+ body_content = self._serialize.body(container_acl, '[SignedIdentifier]', is_xml=True, serialization_ctxt=serialization_ctxt)
+ else:
+ body_content = None
+ body_content_kwargs['content'] = body_content
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_access_policy.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def restore(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ deleted_container_name: Optional[str] = None,
+ deleted_container_version: Optional[str] = None,
+ **kwargs: Any
+ ) -> None:
+ """Restores a previously-deleted container.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param deleted_container_name: Optional. Version 2019-12-12 and later. Specifies the name of
+ the deleted container to restore.
+ :type deleted_container_name: str
+ :param deleted_container_version: Optional. Version 2019-12-12 and later. Specifies the
+ version of the deleted container to restore.
+ :type deleted_container_version: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "undelete"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.restore.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if deleted_container_name is not None:
+ header_parameters['x-ms-deleted-container-name'] = self._serialize.header("deleted_container_name", deleted_container_name, 'str')
+ if deleted_container_version is not None:
+ header_parameters['x-ms-deleted-container-version'] = self._serialize.header("deleted_container_version", deleted_container_version, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ restore.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def rename(
+ self,
+ source_container_name: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ source_lease_id: Optional[str] = None,
+ **kwargs: Any
+ ) -> None:
+ """Renames an existing container.
+
+ :param source_container_name: Required. Specifies the name of the container to rename.
+ :type source_container_name: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param source_lease_id: A lease ID for the source path. If specified, the source path must have
+ an active lease and the lease ID must match.
+ :type source_lease_id: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "rename"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.rename.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['x-ms-source-container-name'] = self._serialize.header("source_container_name", source_container_name, 'str')
+ if source_lease_id is not None:
+ header_parameters['x-ms-source-lease-id'] = self._serialize.header("source_lease_id", source_lease_id, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ rename.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def submit_batch(
+ self,
+ content_length: int,
+ multipart_content_type: str,
+ body: IO,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> IO:
+ """The Batch operation allows multiple API calls to be embedded into a single HTTP request.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param multipart_content_type: Required. The value of this header must be multipart/mixed with
+ a batch boundary. Example header value: multipart/mixed; boundary=batch_:code:``.
+ :type multipart_content_type: str
+ :param body: Initial data.
+ :type body: IO
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: IO, or the result of cls(response)
+ :rtype: IO
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[IO]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "batch"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.submit_batch.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ header_parameters['Content-Type'] = self._serialize.header("multipart_content_type", multipart_content_type, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(body, 'IO', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=True, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ submit_batch.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def filter_blobs(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ where: Optional[str] = None,
+ marker: Optional[str] = None,
+ maxresults: Optional[int] = None,
+ **kwargs: Any
+ ) -> "_models.FilterBlobSegment":
+ """The Filter Blobs operation enables callers to list blobs in a container whose tags match a
+ given search expression. Filter blobs searches within the given container.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param where: Filters the results to return only to return only blobs whose tags match the
+ specified expression.
+ :type where: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: FilterBlobSegment, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.FilterBlobSegment
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.FilterBlobSegment"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "blobs"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.filter_blobs.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if where is not None:
+ query_parameters['where'] = self._serialize.query("where", where, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('FilterBlobSegment', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ filter_blobs.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def acquire_lease(
+ self,
+ timeout: Optional[int] = None,
+ duration: Optional[int] = None,
+ proposed_lease_id: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param duration: Specifies the duration of the lease, in seconds, or negative one (-1) for a
+ lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease
+ duration cannot be changed using renew or change.
+ :type duration: int
+ :param proposed_lease_id: Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid
+ Constructor (String) for a list of valid GUID string formats.
+ :type proposed_lease_id: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "acquire"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.acquire_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ if duration is not None:
+ header_parameters['x-ms-lease-duration'] = self._serialize.header("duration", duration, 'int')
+ if proposed_lease_id is not None:
+ header_parameters['x-ms-proposed-lease-id'] = self._serialize.header("proposed_lease_id", proposed_lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ acquire_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def release_lease(
+ self,
+ lease_id: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "release"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.release_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ release_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def renew_lease(
+ self,
+ lease_id: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "renew"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.renew_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ renew_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def break_lease(
+ self,
+ timeout: Optional[int] = None,
+ break_period: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param break_period: For a break operation, proposed duration the lease should continue before
+ it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter
+ than the time remaining on the lease. If longer, the time remaining on the lease is used. A new
+ lease will not be available before the break period has expired, but the lease may be held for
+ longer than the break period. If this header does not appear with a break operation, a
+ fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease
+ breaks immediately.
+ :type break_period: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "break"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.break_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ if break_period is not None:
+ header_parameters['x-ms-lease-break-period'] = self._serialize.header("break_period", break_period, 'int')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-time']=self._deserialize('int', response.headers.get('x-ms-lease-time'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ break_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def change_lease(
+ self,
+ lease_id: str,
+ proposed_lease_id: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param proposed_lease_id: Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid
+ Constructor (String) for a list of valid GUID string formats.
+ :type proposed_lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "change"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.change_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ header_parameters['x-ms-proposed-lease-id'] = self._serialize.header("proposed_lease_id", proposed_lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ change_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def list_blob_flat_segment(
+ self,
+ prefix: Optional[str] = None,
+ marker: Optional[str] = None,
+ maxresults: Optional[int] = None,
+ include: Optional[List[Union[str, "_models.ListBlobsIncludeItem"]]] = None,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> "_models.ListBlobsFlatSegmentResponse":
+ """[Update] The List Blobs operation returns a list of the blobs under the specified container.
+
+ :param prefix: Filters the results to return only containers whose name begins with the
+ specified prefix.
+ :type prefix: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :param include: Include this parameter to specify one or more datasets to include in the
+ response.
+ :type include: list[str or ~azure.storage.blob.models.ListBlobsIncludeItem]
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: ListBlobsFlatSegmentResponse, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.ListBlobsFlatSegmentResponse
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.ListBlobsFlatSegmentResponse"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "list"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.list_blob_flat_segment.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if prefix is not None:
+ query_parameters['prefix'] = self._serialize.query("prefix", prefix, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+ if include is not None:
+ query_parameters['include'] = self._serialize.query("include", include, '[str]', div=',')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('ListBlobsFlatSegmentResponse', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ list_blob_flat_segment.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def list_blob_hierarchy_segment(
+ self,
+ delimiter: str,
+ prefix: Optional[str] = None,
+ marker: Optional[str] = None,
+ maxresults: Optional[int] = None,
+ include: Optional[List[Union[str, "_models.ListBlobsIncludeItem"]]] = None,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> "_models.ListBlobsHierarchySegmentResponse":
+ """[Update] The List Blobs operation returns a list of the blobs under the specified container.
+
+ :param delimiter: When the request includes this parameter, the operation returns a BlobPrefix
+ element in the response body that acts as a placeholder for all blobs whose names begin with
+ the same substring up to the appearance of the delimiter character. The delimiter may be a
+ single character or a string.
+ :type delimiter: str
+ :param prefix: Filters the results to return only containers whose name begins with the
+ specified prefix.
+ :type prefix: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :param include: Include this parameter to specify one or more datasets to include in the
+ response.
+ :type include: list[str or ~azure.storage.blob.models.ListBlobsIncludeItem]
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: ListBlobsHierarchySegmentResponse, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.ListBlobsHierarchySegmentResponse
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.ListBlobsHierarchySegmentResponse"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "list"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.list_blob_hierarchy_segment.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if prefix is not None:
+ query_parameters['prefix'] = self._serialize.query("prefix", prefix, 'str')
+ query_parameters['delimiter'] = self._serialize.query("delimiter", delimiter, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+ if include is not None:
+ query_parameters['include'] = self._serialize.query("include", include, '[str]', div=',')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('ListBlobsHierarchySegmentResponse', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ list_blob_hierarchy_segment.metadata = {'url': '/{containerName}'} # type: ignore
+
+ async def get_account_info(
+ self,
+ **kwargs: Any
+ ) -> None:
+ """Returns the sku name and account kind.
+
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "account"
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_account_info.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-sku-name']=self._deserialize('str', response.headers.get('x-ms-sku-name'))
+ response_headers['x-ms-account-kind']=self._deserialize('str', response.headers.get('x-ms-account-kind'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_account_info.metadata = {'url': '/{containerName}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_page_blob_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_page_blob_operations.py
new file mode 100644
index 00000000000..06f17558bd2
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_page_blob_operations.py
@@ -0,0 +1,1424 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest
+
+from ... import models as _models
+
+T = TypeVar('T')
+ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]]
+
+class PageBlobOperations:
+ """PageBlobOperations async operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer) -> None:
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ async def create(
+ self,
+ content_length: int,
+ blob_content_length: int,
+ timeout: Optional[int] = None,
+ tier: Optional[Union[str, "_models.PremiumPageBlobAccessTier"]] = None,
+ metadata: Optional[str] = None,
+ blob_sequence_number: Optional[int] = 0,
+ request_id_parameter: Optional[str] = None,
+ blob_tags_string: Optional[str] = None,
+ immutability_policy_expiry: Optional[datetime.datetime] = None,
+ immutability_policy_mode: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]] = None,
+ legal_hold: Optional[bool] = None,
+ blob_http_headers: Optional["_models.BlobHTTPHeaders"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Create operation creates a new page blob.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param blob_content_length: This header specifies the maximum size for the page blob, up to 1
+ TB. The page blob size must be aligned to a 512-byte boundary.
+ :type blob_content_length: long
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param tier: Optional. Indicates the tier to be set on the page blob.
+ :type tier: str or ~azure.storage.blob.models.PremiumPageBlobAccessTier
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param blob_sequence_number: Set for page blobs only. The sequence number is a user-controlled
+ value that you can use to track requests. The value of the sequence number must be between 0
+ and 2^63 - 1.
+ :type blob_sequence_number: long
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _blob_cache_control = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if blob_http_headers is not None:
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ blob_type = "PageBlob"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.create.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-blob-content-length'] = self._serialize.header("blob_content_length", blob_content_length, 'long')
+ if blob_sequence_number is not None:
+ header_parameters['x-ms-blob-sequence-number'] = self._serialize.header("blob_sequence_number", blob_sequence_number, 'long')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ create.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def upload_pages(
+ self,
+ content_length: int,
+ body: IO,
+ transactional_content_md5: Optional[bytearray] = None,
+ transactional_content_crc64: Optional[bytearray] = None,
+ timeout: Optional[int] = None,
+ range: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ sequence_number_access_conditions: Optional["_models.SequenceNumberAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Upload Pages operation writes a range of pages to a page blob.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param body: Initial data.
+ :type body: IO
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param sequence_number_access_conditions: Parameter group.
+ :type sequence_number_access_conditions: ~azure.storage.blob.models.SequenceNumberAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_sequence_number_less_than_or_equal_to = None
+ _if_sequence_number_less_than = None
+ _if_sequence_number_equal_to = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if sequence_number_access_conditions is not None:
+ _if_sequence_number_less_than_or_equal_to = sequence_number_access_conditions.if_sequence_number_less_than_or_equal_to
+ _if_sequence_number_less_than = sequence_number_access_conditions.if_sequence_number_less_than
+ _if_sequence_number_equal_to = sequence_number_access_conditions.if_sequence_number_equal_to
+ comp = "page"
+ page_write = "update"
+ content_type = kwargs.pop("content_type", "application/octet-stream")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.upload_pages.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-page-write'] = self._serialize.header("page_write", page_write, 'str')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_sequence_number_less_than_or_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-le'] = self._serialize.header("if_sequence_number_less_than_or_equal_to", _if_sequence_number_less_than_or_equal_to, 'long')
+ if _if_sequence_number_less_than is not None:
+ header_parameters['x-ms-if-sequence-number-lt'] = self._serialize.header("if_sequence_number_less_than", _if_sequence_number_less_than, 'long')
+ if _if_sequence_number_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-eq'] = self._serialize.header("if_sequence_number_equal_to", _if_sequence_number_equal_to, 'long')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content_kwargs['stream_content'] = body
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ upload_pages.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def clear_pages(
+ self,
+ content_length: int,
+ timeout: Optional[int] = None,
+ range: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ sequence_number_access_conditions: Optional["_models.SequenceNumberAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Clear Pages operation clears a set of pages from a page blob.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param sequence_number_access_conditions: Parameter group.
+ :type sequence_number_access_conditions: ~azure.storage.blob.models.SequenceNumberAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_sequence_number_less_than_or_equal_to = None
+ _if_sequence_number_less_than = None
+ _if_sequence_number_equal_to = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if sequence_number_access_conditions is not None:
+ _if_sequence_number_less_than_or_equal_to = sequence_number_access_conditions.if_sequence_number_less_than_or_equal_to
+ _if_sequence_number_less_than = sequence_number_access_conditions.if_sequence_number_less_than
+ _if_sequence_number_equal_to = sequence_number_access_conditions.if_sequence_number_equal_to
+ comp = "page"
+ page_write = "clear"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.clear_pages.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-page-write'] = self._serialize.header("page_write", page_write, 'str')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_sequence_number_less_than_or_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-le'] = self._serialize.header("if_sequence_number_less_than_or_equal_to", _if_sequence_number_less_than_or_equal_to, 'long')
+ if _if_sequence_number_less_than is not None:
+ header_parameters['x-ms-if-sequence-number-lt'] = self._serialize.header("if_sequence_number_less_than", _if_sequence_number_less_than, 'long')
+ if _if_sequence_number_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-eq'] = self._serialize.header("if_sequence_number_equal_to", _if_sequence_number_equal_to, 'long')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ clear_pages.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def upload_pages_from_url(
+ self,
+ source_url: str,
+ source_range: str,
+ content_length: int,
+ range: str,
+ source_content_md5: Optional[bytearray] = None,
+ source_contentcrc64: Optional[bytearray] = None,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ copy_source_authorization: Optional[str] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ sequence_number_access_conditions: Optional["_models.SequenceNumberAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ source_modified_access_conditions: Optional["_models.SourceModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Upload Pages operation writes a range of pages to a page blob where the contents are read
+ from a URL.
+
+ :param source_url: Specify a URL to the copy source.
+ :type source_url: str
+ :param source_range: Bytes of source data in the specified range. The length of this range
+ should match the ContentLength header and x-ms-range/Range destination range header.
+ :type source_range: str
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param range: The range of bytes to which the source range would be written. The range should
+ be 512 aligned and range-end is required.
+ :type range: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param source_contentcrc64: Specify the crc64 calculated for the range of bytes that must be
+ read from the copy source.
+ :type source_contentcrc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param sequence_number_access_conditions: Parameter group.
+ :type sequence_number_access_conditions: ~azure.storage.blob.models.SequenceNumberAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _lease_id = None
+ _if_sequence_number_less_than_or_equal_to = None
+ _if_sequence_number_less_than = None
+ _if_sequence_number_equal_to = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if sequence_number_access_conditions is not None:
+ _if_sequence_number_less_than_or_equal_to = sequence_number_access_conditions.if_sequence_number_less_than_or_equal_to
+ _if_sequence_number_less_than = sequence_number_access_conditions.if_sequence_number_less_than
+ _if_sequence_number_equal_to = sequence_number_access_conditions.if_sequence_number_equal_to
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ comp = "page"
+ page_write = "update"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.upload_pages_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-page-write'] = self._serialize.header("page_write", page_write, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("source_url", source_url, 'str')
+ header_parameters['x-ms-source-range'] = self._serialize.header("source_range", source_range, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if source_contentcrc64 is not None:
+ header_parameters['x-ms-source-content-crc64'] = self._serialize.header("source_contentcrc64", source_contentcrc64, 'bytearray')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_sequence_number_less_than_or_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-le'] = self._serialize.header("if_sequence_number_less_than_or_equal_to", _if_sequence_number_less_than_or_equal_to, 'long')
+ if _if_sequence_number_less_than is not None:
+ header_parameters['x-ms-if-sequence-number-lt'] = self._serialize.header("if_sequence_number_less_than", _if_sequence_number_less_than, 'long')
+ if _if_sequence_number_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-eq'] = self._serialize.header("if_sequence_number_equal_to", _if_sequence_number_equal_to, 'long')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ upload_pages_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def get_page_ranges(
+ self,
+ snapshot: Optional[str] = None,
+ timeout: Optional[int] = None,
+ range: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> "_models.PageList":
+ """The Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot
+ of a page blob.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: PageList, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.PageList
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.PageList"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "pagelist"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_page_ranges.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['x-ms-blob-content-length']=self._deserialize('long', response.headers.get('x-ms-blob-content-length'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('PageList', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_page_ranges.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def get_page_ranges_diff(
+ self,
+ snapshot: Optional[str] = None,
+ timeout: Optional[int] = None,
+ prevsnapshot: Optional[str] = None,
+ prev_snapshot_url: Optional[str] = None,
+ range: Optional[str] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> "_models.PageList":
+ """The Get Page Ranges Diff operation returns the list of valid page ranges for a page blob that
+ were changed between target blob and previous snapshot.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param prevsnapshot: Optional in version 2015-07-08 and newer. The prevsnapshot parameter is a
+ DateTime value that specifies that the response will contain only pages that were changed
+ between target blob and previous snapshot. Changed pages include both updated and cleared
+ pages. The target blob may be a snapshot, as long as the snapshot specified by prevsnapshot is
+ the older of the two. Note that incremental snapshots are currently supported only for blobs
+ created on or after January 1, 2016.
+ :type prevsnapshot: str
+ :param prev_snapshot_url: Optional. This header is only supported in service versions
+ 2019-04-19 and after and specifies the URL of a previous snapshot of the target blob. The
+ response will only contain pages that were changed between the target blob and its previous
+ snapshot.
+ :type prev_snapshot_url: str
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: PageList, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.PageList
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.PageList"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "pagelist"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_page_ranges_diff.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if prevsnapshot is not None:
+ query_parameters['prevsnapshot'] = self._serialize.query("prevsnapshot", prevsnapshot, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if prev_snapshot_url is not None:
+ header_parameters['x-ms-previous-snapshot-url'] = self._serialize.header("prev_snapshot_url", prev_snapshot_url, 'str')
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['x-ms-blob-content-length']=self._deserialize('long', response.headers.get('x-ms-blob-content-length'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('PageList', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_page_ranges_diff.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def resize(
+ self,
+ blob_content_length: int,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ cpk_info: Optional["_models.CpkInfo"] = None,
+ cpk_scope_info: Optional["_models.CpkScopeInfo"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """Resize the Blob.
+
+ :param blob_content_length: This header specifies the maximum size for the page blob, up to 1
+ TB. The page blob size must be aligned to a 512-byte boundary.
+ :type blob_content_length: long
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.resize.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-blob-content-length'] = self._serialize.header("blob_content_length", blob_content_length, 'long')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ resize.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def update_sequence_number(
+ self,
+ sequence_number_action: Union[str, "_models.SequenceNumberActionType"],
+ timeout: Optional[int] = None,
+ blob_sequence_number: Optional[int] = 0,
+ request_id_parameter: Optional[str] = None,
+ lease_access_conditions: Optional["_models.LeaseAccessConditions"] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """Update the sequence number of the blob.
+
+ :param sequence_number_action: Required if the x-ms-blob-sequence-number header is set for the
+ request. This property applies to page blobs only. This property indicates how the service
+ should modify the blob's sequence number.
+ :type sequence_number_action: str or ~azure.storage.blob.models.SequenceNumberActionType
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param blob_sequence_number: Set for page blobs only. The sequence number is a user-controlled
+ value that you can use to track requests. The value of the sequence number must be between 0
+ and 2^63 - 1.
+ :type blob_sequence_number: long
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.update_sequence_number.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-sequence-number-action'] = self._serialize.header("sequence_number_action", sequence_number_action, 'str')
+ if blob_sequence_number is not None:
+ header_parameters['x-ms-blob-sequence-number'] = self._serialize.header("blob_sequence_number", blob_sequence_number, 'long')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ update_sequence_number.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ async def copy_incremental(
+ self,
+ copy_source: str,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ modified_access_conditions: Optional["_models.ModifiedAccessConditions"] = None,
+ **kwargs: Any
+ ) -> None:
+ """The Copy Incremental operation copies a snapshot of the source page blob to a destination page
+ blob. The snapshot is copied such that only the differential changes between the previously
+ copied snapshot are transferred to the destination. The copied snapshots are complete copies of
+ the original snapshot and can be read or copied from as usual. This API is supported since REST
+ version 2016-05-31.
+
+ :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
+ up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
+ would appear in a request URI. The source blob must either be public or must be authenticated
+ via a shared access signature.
+ :type copy_source: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "incrementalcopy"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.copy_incremental.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ copy_incremental.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_service_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_service_operations.py
new file mode 100644
index 00000000000..a6592a33f7f
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/aio/operations/_service_operations.py
@@ -0,0 +1,698 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+from typing import Any, Callable, Dict, Generic, IO, List, Optional, TypeVar, Union
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest
+
+from ... import models as _models
+
+T = TypeVar('T')
+ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]]
+
+class ServiceOperations:
+ """ServiceOperations async operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer) -> None:
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ async def set_properties(
+ self,
+ storage_service_properties: "_models.StorageServiceProperties",
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> None:
+ """Sets properties for a storage account's Blob service endpoint, including properties for Storage
+ Analytics and CORS (Cross-Origin Resource Sharing) rules.
+
+ :param storage_service_properties: The StorageService properties.
+ :type storage_service_properties: ~azure.storage.blob.models.StorageServiceProperties
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "service"
+ comp = "properties"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_properties.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(storage_service_properties, 'StorageServiceProperties', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_properties.metadata = {'url': '/'} # type: ignore
+
+ async def get_properties(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> "_models.StorageServiceProperties":
+ """gets the properties of a storage account's Blob service, including properties for Storage
+ Analytics and CORS (Cross-Origin Resource Sharing) rules.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: StorageServiceProperties, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.StorageServiceProperties
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.StorageServiceProperties"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "service"
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_properties.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ deserialized = self._deserialize('StorageServiceProperties', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_properties.metadata = {'url': '/'} # type: ignore
+
+ async def get_statistics(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> "_models.StorageServiceStats":
+ """Retrieves statistics related to replication for the Blob service. It is only available on the
+ secondary location endpoint when read-access geo-redundant replication is enabled for the
+ storage account.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: StorageServiceStats, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.StorageServiceStats
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.StorageServiceStats"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "service"
+ comp = "stats"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_statistics.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('StorageServiceStats', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_statistics.metadata = {'url': '/'} # type: ignore
+
+ async def list_containers_segment(
+ self,
+ prefix: Optional[str] = None,
+ marker: Optional[str] = None,
+ maxresults: Optional[int] = None,
+ include: Optional[List[Union[str, "_models.ListContainersIncludeType"]]] = None,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> "_models.ListContainersSegmentResponse":
+ """The List Containers Segment operation returns a list of the containers under the specified
+ account.
+
+ :param prefix: Filters the results to return only containers whose name begins with the
+ specified prefix.
+ :type prefix: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :param include: Include this parameter to specify that the container's metadata be returned as
+ part of the response body.
+ :type include: list[str or ~azure.storage.blob.models.ListContainersIncludeType]
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: ListContainersSegmentResponse, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.ListContainersSegmentResponse
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.ListContainersSegmentResponse"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "list"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.list_containers_segment.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if prefix is not None:
+ query_parameters['prefix'] = self._serialize.query("prefix", prefix, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+ if include is not None:
+ query_parameters['include'] = self._serialize.query("include", include, '[str]', div=',')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ deserialized = self._deserialize('ListContainersSegmentResponse', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ list_containers_segment.metadata = {'url': '/'} # type: ignore
+
+ async def get_user_delegation_key(
+ self,
+ key_info: "_models.KeyInfo",
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> "_models.UserDelegationKey":
+ """Retrieves a user delegation key for the Blob service. This is only a valid operation when using
+ bearer token authentication.
+
+ :param key_info: Key information.
+ :type key_info: ~azure.storage.blob.models.KeyInfo
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: UserDelegationKey, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.UserDelegationKey
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.UserDelegationKey"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "service"
+ comp = "userdelegationkey"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_user_delegation_key.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(key_info, 'KeyInfo', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('UserDelegationKey', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_user_delegation_key.metadata = {'url': '/'} # type: ignore
+
+ async def get_account_info(
+ self,
+ **kwargs: Any
+ ) -> None:
+ """Returns the sku name and account kind.
+
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "account"
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_account_info.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-sku-name']=self._deserialize('str', response.headers.get('x-ms-sku-name'))
+ response_headers['x-ms-account-kind']=self._deserialize('str', response.headers.get('x-ms-account-kind'))
+ response_headers['x-ms-is-hns-enabled']=self._deserialize('bool', response.headers.get('x-ms-is-hns-enabled'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_account_info.metadata = {'url': '/'} # type: ignore
+
+ async def submit_batch(
+ self,
+ content_length: int,
+ multipart_content_type: str,
+ body: IO,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ **kwargs: Any
+ ) -> IO:
+ """The Batch operation allows multiple API calls to be embedded into a single HTTP request.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param multipart_content_type: Required. The value of this header must be multipart/mixed with
+ a batch boundary. Example header value: multipart/mixed; boundary=batch_:code:``.
+ :type multipart_content_type: str
+ :param body: Initial data.
+ :type body: IO
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: IO, or the result of cls(response)
+ :rtype: IO
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[IO]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "batch"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.submit_batch.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ header_parameters['Content-Type'] = self._serialize.header("multipart_content_type", multipart_content_type, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(body, 'IO', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = await self._client._pipeline.run(request, stream=True, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ submit_batch.metadata = {'url': '/'} # type: ignore
+
+ async def filter_blobs(
+ self,
+ timeout: Optional[int] = None,
+ request_id_parameter: Optional[str] = None,
+ where: Optional[str] = None,
+ marker: Optional[str] = None,
+ maxresults: Optional[int] = None,
+ **kwargs: Any
+ ) -> "_models.FilterBlobSegment":
+ """The Filter Blobs operation enables callers to list blobs across all containers whose tags match
+ a given search expression. Filter blobs searches across all containers within a storage
+ account but can be scoped within the expression to a single container.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param where: Filters the results to return only to return only blobs whose tags match the
+ specified expression.
+ :type where: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: FilterBlobSegment, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.FilterBlobSegment
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.FilterBlobSegment"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "blobs"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.filter_blobs.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if where is not None:
+ query_parameters['where'] = self._serialize.query("where", where, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('FilterBlobSegment', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ filter_blobs.metadata = {'url': '/'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/__init__.py
new file mode 100644
index 00000000000..e3307ac818b
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/__init__.py
@@ -0,0 +1,219 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+try:
+ from ._models_py3 import AccessPolicy
+ from ._models_py3 import AppendPositionAccessConditions
+ from ._models_py3 import ArrowConfiguration
+ from ._models_py3 import ArrowField
+ from ._models_py3 import BlobFlatListSegment
+ from ._models_py3 import BlobHTTPHeaders
+ from ._models_py3 import BlobHierarchyListSegment
+ from ._models_py3 import BlobItemInternal
+ from ._models_py3 import BlobMetadata
+ from ._models_py3 import BlobName
+ from ._models_py3 import BlobPrefix
+ from ._models_py3 import BlobPropertiesInternal
+ from ._models_py3 import BlobTag
+ from ._models_py3 import BlobTags
+ from ._models_py3 import Block
+ from ._models_py3 import BlockList
+ from ._models_py3 import BlockLookupList
+ from ._models_py3 import ClearRange
+ from ._models_py3 import ContainerCpkScopeInfo
+ from ._models_py3 import ContainerItem
+ from ._models_py3 import ContainerProperties
+ from ._models_py3 import CorsRule
+ from ._models_py3 import CpkInfo
+ from ._models_py3 import CpkScopeInfo
+ from ._models_py3 import DelimitedTextConfiguration
+ from ._models_py3 import FilterBlobItem
+ from ._models_py3 import FilterBlobSegment
+ from ._models_py3 import GeoReplication
+ from ._models_py3 import JsonTextConfiguration
+ from ._models_py3 import KeyInfo
+ from ._models_py3 import LeaseAccessConditions
+ from ._models_py3 import ListBlobsFlatSegmentResponse
+ from ._models_py3 import ListBlobsHierarchySegmentResponse
+ from ._models_py3 import ListContainersSegmentResponse
+ from ._models_py3 import Logging
+ from ._models_py3 import Metrics
+ from ._models_py3 import ModifiedAccessConditions
+ from ._models_py3 import PageList
+ from ._models_py3 import PageRange
+ from ._models_py3 import QueryFormat
+ from ._models_py3 import QueryRequest
+ from ._models_py3 import QuerySerialization
+ from ._models_py3 import RetentionPolicy
+ from ._models_py3 import SequenceNumberAccessConditions
+ from ._models_py3 import SignedIdentifier
+ from ._models_py3 import SourceModifiedAccessConditions
+ from ._models_py3 import StaticWebsite
+ from ._models_py3 import StorageError
+ from ._models_py3 import StorageServiceProperties
+ from ._models_py3 import StorageServiceStats
+ from ._models_py3 import UserDelegationKey
+except (SyntaxError, ImportError):
+ from ._models import AccessPolicy # type: ignore
+ from ._models import AppendPositionAccessConditions # type: ignore
+ from ._models import ArrowConfiguration # type: ignore
+ from ._models import ArrowField # type: ignore
+ from ._models import BlobFlatListSegment # type: ignore
+ from ._models import BlobHTTPHeaders # type: ignore
+ from ._models import BlobHierarchyListSegment # type: ignore
+ from ._models import BlobItemInternal # type: ignore
+ from ._models import BlobMetadata # type: ignore
+ from ._models import BlobName # type: ignore
+ from ._models import BlobPrefix # type: ignore
+ from ._models import BlobPropertiesInternal # type: ignore
+ from ._models import BlobTag # type: ignore
+ from ._models import BlobTags # type: ignore
+ from ._models import Block # type: ignore
+ from ._models import BlockList # type: ignore
+ from ._models import BlockLookupList # type: ignore
+ from ._models import ClearRange # type: ignore
+ from ._models import ContainerCpkScopeInfo # type: ignore
+ from ._models import ContainerItem # type: ignore
+ from ._models import ContainerProperties # type: ignore
+ from ._models import CorsRule # type: ignore
+ from ._models import CpkInfo # type: ignore
+ from ._models import CpkScopeInfo # type: ignore
+ from ._models import DelimitedTextConfiguration # type: ignore
+ from ._models import FilterBlobItem # type: ignore
+ from ._models import FilterBlobSegment # type: ignore
+ from ._models import GeoReplication # type: ignore
+ from ._models import JsonTextConfiguration # type: ignore
+ from ._models import KeyInfo # type: ignore
+ from ._models import LeaseAccessConditions # type: ignore
+ from ._models import ListBlobsFlatSegmentResponse # type: ignore
+ from ._models import ListBlobsHierarchySegmentResponse # type: ignore
+ from ._models import ListContainersSegmentResponse # type: ignore
+ from ._models import Logging # type: ignore
+ from ._models import Metrics # type: ignore
+ from ._models import ModifiedAccessConditions # type: ignore
+ from ._models import PageList # type: ignore
+ from ._models import PageRange # type: ignore
+ from ._models import QueryFormat # type: ignore
+ from ._models import QueryRequest # type: ignore
+ from ._models import QuerySerialization # type: ignore
+ from ._models import RetentionPolicy # type: ignore
+ from ._models import SequenceNumberAccessConditions # type: ignore
+ from ._models import SignedIdentifier # type: ignore
+ from ._models import SourceModifiedAccessConditions # type: ignore
+ from ._models import StaticWebsite # type: ignore
+ from ._models import StorageError # type: ignore
+ from ._models import StorageServiceProperties # type: ignore
+ from ._models import StorageServiceStats # type: ignore
+ from ._models import UserDelegationKey # type: ignore
+
+from ._azure_blob_storage_enums import (
+ AccessTier,
+ AccessTierOptional,
+ AccessTierRequired,
+ AccountKind,
+ ArchiveStatus,
+ BlobExpiryOptions,
+ BlobImmutabilityPolicyMode,
+ BlobType,
+ BlockListType,
+ CopyStatusType,
+ DeleteSnapshotsOptionType,
+ EncryptionAlgorithmType,
+ GeoReplicationStatusType,
+ LeaseDurationType,
+ LeaseStateType,
+ LeaseStatusType,
+ ListBlobsIncludeItem,
+ ListContainersIncludeType,
+ PremiumPageBlobAccessTier,
+ PublicAccessType,
+ QueryFormatType,
+ RehydratePriority,
+ SequenceNumberActionType,
+ SkuName,
+ StorageErrorCode,
+)
+
+__all__ = [
+ 'AccessPolicy',
+ 'AppendPositionAccessConditions',
+ 'ArrowConfiguration',
+ 'ArrowField',
+ 'BlobFlatListSegment',
+ 'BlobHTTPHeaders',
+ 'BlobHierarchyListSegment',
+ 'BlobItemInternal',
+ 'BlobMetadata',
+ 'BlobName',
+ 'BlobPrefix',
+ 'BlobPropertiesInternal',
+ 'BlobTag',
+ 'BlobTags',
+ 'Block',
+ 'BlockList',
+ 'BlockLookupList',
+ 'ClearRange',
+ 'ContainerCpkScopeInfo',
+ 'ContainerItem',
+ 'ContainerProperties',
+ 'CorsRule',
+ 'CpkInfo',
+ 'CpkScopeInfo',
+ 'DelimitedTextConfiguration',
+ 'FilterBlobItem',
+ 'FilterBlobSegment',
+ 'GeoReplication',
+ 'JsonTextConfiguration',
+ 'KeyInfo',
+ 'LeaseAccessConditions',
+ 'ListBlobsFlatSegmentResponse',
+ 'ListBlobsHierarchySegmentResponse',
+ 'ListContainersSegmentResponse',
+ 'Logging',
+ 'Metrics',
+ 'ModifiedAccessConditions',
+ 'PageList',
+ 'PageRange',
+ 'QueryFormat',
+ 'QueryRequest',
+ 'QuerySerialization',
+ 'RetentionPolicy',
+ 'SequenceNumberAccessConditions',
+ 'SignedIdentifier',
+ 'SourceModifiedAccessConditions',
+ 'StaticWebsite',
+ 'StorageError',
+ 'StorageServiceProperties',
+ 'StorageServiceStats',
+ 'UserDelegationKey',
+ 'AccessTier',
+ 'AccessTierOptional',
+ 'AccessTierRequired',
+ 'AccountKind',
+ 'ArchiveStatus',
+ 'BlobExpiryOptions',
+ 'BlobImmutabilityPolicyMode',
+ 'BlobType',
+ 'BlockListType',
+ 'CopyStatusType',
+ 'DeleteSnapshotsOptionType',
+ 'EncryptionAlgorithmType',
+ 'GeoReplicationStatusType',
+ 'LeaseDurationType',
+ 'LeaseStateType',
+ 'LeaseStatusType',
+ 'ListBlobsIncludeItem',
+ 'ListContainersIncludeType',
+ 'PremiumPageBlobAccessTier',
+ 'PublicAccessType',
+ 'QueryFormatType',
+ 'RehydratePriority',
+ 'SequenceNumberActionType',
+ 'SkuName',
+ 'StorageErrorCode',
+]
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_azure_blob_storage_enums.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_azure_blob_storage_enums.py
new file mode 100644
index 00000000000..31325457b82
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_azure_blob_storage_enums.py
@@ -0,0 +1,346 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from enum import Enum, EnumMeta
+from six import with_metaclass
+
+class _CaseInsensitiveEnumMeta(EnumMeta):
+ def __getitem__(self, name):
+ return super().__getitem__(name.upper())
+
+ def __getattr__(cls, name):
+ """Return the enum member matching `name`
+ We use __getattr__ instead of descriptors or inserting into the enum
+ class' __dict__ in order to support `name` and `value` being both
+ properties for enum members (which live in the class' __dict__) and
+ enum members themselves.
+ """
+ try:
+ return cls._member_map_[name.upper()]
+ except KeyError:
+ raise AttributeError(name)
+
+
+class AccessTier(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ P4 = "P4"
+ P6 = "P6"
+ P10 = "P10"
+ P15 = "P15"
+ P20 = "P20"
+ P30 = "P30"
+ P40 = "P40"
+ P50 = "P50"
+ P60 = "P60"
+ P70 = "P70"
+ P80 = "P80"
+ HOT = "Hot"
+ COOL = "Cool"
+ ARCHIVE = "Archive"
+
+class AccessTierOptional(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ P4 = "P4"
+ P6 = "P6"
+ P10 = "P10"
+ P15 = "P15"
+ P20 = "P20"
+ P30 = "P30"
+ P40 = "P40"
+ P50 = "P50"
+ P60 = "P60"
+ P70 = "P70"
+ P80 = "P80"
+ HOT = "Hot"
+ COOL = "Cool"
+ ARCHIVE = "Archive"
+
+class AccessTierRequired(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ P4 = "P4"
+ P6 = "P6"
+ P10 = "P10"
+ P15 = "P15"
+ P20 = "P20"
+ P30 = "P30"
+ P40 = "P40"
+ P50 = "P50"
+ P60 = "P60"
+ P70 = "P70"
+ P80 = "P80"
+ HOT = "Hot"
+ COOL = "Cool"
+ ARCHIVE = "Archive"
+
+class AccountKind(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ STORAGE = "Storage"
+ BLOB_STORAGE = "BlobStorage"
+ STORAGE_V2 = "StorageV2"
+ FILE_STORAGE = "FileStorage"
+ BLOCK_BLOB_STORAGE = "BlockBlobStorage"
+
+class ArchiveStatus(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ REHYDRATE_PENDING_TO_HOT = "rehydrate-pending-to-hot"
+ REHYDRATE_PENDING_TO_COOL = "rehydrate-pending-to-cool"
+
+class BlobExpiryOptions(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ NEVER_EXPIRE = "NeverExpire"
+ RELATIVE_TO_CREATION = "RelativeToCreation"
+ RELATIVE_TO_NOW = "RelativeToNow"
+ ABSOLUTE = "Absolute"
+
+class BlobImmutabilityPolicyMode(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ MUTABLE = "Mutable"
+ UNLOCKED = "Unlocked"
+ LOCKED = "Locked"
+
+class BlobType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ BLOCK_BLOB = "BlockBlob"
+ PAGE_BLOB = "PageBlob"
+ APPEND_BLOB = "AppendBlob"
+
+class BlockListType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ COMMITTED = "committed"
+ UNCOMMITTED = "uncommitted"
+ ALL = "all"
+
+class CopyStatusType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ PENDING = "pending"
+ SUCCESS = "success"
+ ABORTED = "aborted"
+ FAILED = "failed"
+
+class DeleteSnapshotsOptionType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ INCLUDE = "include"
+ ONLY = "only"
+
+class EncryptionAlgorithmType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ NONE = "None"
+ AES256 = "AES256"
+
+class GeoReplicationStatusType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+ """The status of the secondary location
+ """
+
+ LIVE = "live"
+ BOOTSTRAP = "bootstrap"
+ UNAVAILABLE = "unavailable"
+
+class LeaseDurationType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ INFINITE = "infinite"
+ FIXED = "fixed"
+
+class LeaseStateType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ AVAILABLE = "available"
+ LEASED = "leased"
+ EXPIRED = "expired"
+ BREAKING = "breaking"
+ BROKEN = "broken"
+
+class LeaseStatusType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ LOCKED = "locked"
+ UNLOCKED = "unlocked"
+
+class ListBlobsIncludeItem(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ COPY = "copy"
+ DELETED = "deleted"
+ METADATA = "metadata"
+ SNAPSHOTS = "snapshots"
+ UNCOMMITTEDBLOBS = "uncommittedblobs"
+ VERSIONS = "versions"
+ TAGS = "tags"
+ IMMUTABILITYPOLICY = "immutabilitypolicy"
+ LEGALHOLD = "legalhold"
+ DELETEDWITHVERSIONS = "deletedwithversions"
+
+class ListContainersIncludeType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ METADATA = "metadata"
+ DELETED = "deleted"
+ SYSTEM = "system"
+
+class PremiumPageBlobAccessTier(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ P4 = "P4"
+ P6 = "P6"
+ P10 = "P10"
+ P15 = "P15"
+ P20 = "P20"
+ P30 = "P30"
+ P40 = "P40"
+ P50 = "P50"
+ P60 = "P60"
+ P70 = "P70"
+ P80 = "P80"
+
+class PublicAccessType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ CONTAINER = "container"
+ BLOB = "blob"
+
+class QueryFormatType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+ """The quick query format type.
+ """
+
+ DELIMITED = "delimited"
+ JSON = "json"
+ ARROW = "arrow"
+ PARQUET = "parquet"
+
+class RehydratePriority(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+ """If an object is in rehydrate pending state then this header is returned with priority of
+ rehydrate. Valid values are High and Standard.
+ """
+
+ HIGH = "High"
+ STANDARD = "Standard"
+
+class SequenceNumberActionType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ MAX = "max"
+ UPDATE = "update"
+ INCREMENT = "increment"
+
+class SkuName(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+
+ STANDARD_LRS = "Standard_LRS"
+ STANDARD_GRS = "Standard_GRS"
+ STANDARD_RAGRS = "Standard_RAGRS"
+ STANDARD_ZRS = "Standard_ZRS"
+ PREMIUM_LRS = "Premium_LRS"
+
+class StorageErrorCode(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
+ """Error codes returned by the service
+ """
+
+ ACCOUNT_ALREADY_EXISTS = "AccountAlreadyExists"
+ ACCOUNT_BEING_CREATED = "AccountBeingCreated"
+ ACCOUNT_IS_DISABLED = "AccountIsDisabled"
+ AUTHENTICATION_FAILED = "AuthenticationFailed"
+ AUTHORIZATION_FAILURE = "AuthorizationFailure"
+ CONDITION_HEADERS_NOT_SUPPORTED = "ConditionHeadersNotSupported"
+ CONDITION_NOT_MET = "ConditionNotMet"
+ EMPTY_METADATA_KEY = "EmptyMetadataKey"
+ INSUFFICIENT_ACCOUNT_PERMISSIONS = "InsufficientAccountPermissions"
+ INTERNAL_ERROR = "InternalError"
+ INVALID_AUTHENTICATION_INFO = "InvalidAuthenticationInfo"
+ INVALID_HEADER_VALUE = "InvalidHeaderValue"
+ INVALID_HTTP_VERB = "InvalidHttpVerb"
+ INVALID_INPUT = "InvalidInput"
+ INVALID_MD5 = "InvalidMd5"
+ INVALID_METADATA = "InvalidMetadata"
+ INVALID_QUERY_PARAMETER_VALUE = "InvalidQueryParameterValue"
+ INVALID_RANGE = "InvalidRange"
+ INVALID_RESOURCE_NAME = "InvalidResourceName"
+ INVALID_URI = "InvalidUri"
+ INVALID_XML_DOCUMENT = "InvalidXmlDocument"
+ INVALID_XML_NODE_VALUE = "InvalidXmlNodeValue"
+ MD5_MISMATCH = "Md5Mismatch"
+ METADATA_TOO_LARGE = "MetadataTooLarge"
+ MISSING_CONTENT_LENGTH_HEADER = "MissingContentLengthHeader"
+ MISSING_REQUIRED_QUERY_PARAMETER = "MissingRequiredQueryParameter"
+ MISSING_REQUIRED_HEADER = "MissingRequiredHeader"
+ MISSING_REQUIRED_XML_NODE = "MissingRequiredXmlNode"
+ MULTIPLE_CONDITION_HEADERS_NOT_SUPPORTED = "MultipleConditionHeadersNotSupported"
+ OPERATION_TIMED_OUT = "OperationTimedOut"
+ OUT_OF_RANGE_INPUT = "OutOfRangeInput"
+ OUT_OF_RANGE_QUERY_PARAMETER_VALUE = "OutOfRangeQueryParameterValue"
+ REQUEST_BODY_TOO_LARGE = "RequestBodyTooLarge"
+ RESOURCE_TYPE_MISMATCH = "ResourceTypeMismatch"
+ REQUEST_URL_FAILED_TO_PARSE = "RequestUrlFailedToParse"
+ RESOURCE_ALREADY_EXISTS = "ResourceAlreadyExists"
+ RESOURCE_NOT_FOUND = "ResourceNotFound"
+ SERVER_BUSY = "ServerBusy"
+ UNSUPPORTED_HEADER = "UnsupportedHeader"
+ UNSUPPORTED_XML_NODE = "UnsupportedXmlNode"
+ UNSUPPORTED_QUERY_PARAMETER = "UnsupportedQueryParameter"
+ UNSUPPORTED_HTTP_VERB = "UnsupportedHttpVerb"
+ APPEND_POSITION_CONDITION_NOT_MET = "AppendPositionConditionNotMet"
+ BLOB_ALREADY_EXISTS = "BlobAlreadyExists"
+ BLOB_IMMUTABLE_DUE_TO_POLICY = "BlobImmutableDueToPolicy"
+ BLOB_NOT_FOUND = "BlobNotFound"
+ BLOB_OVERWRITTEN = "BlobOverwritten"
+ BLOB_TIER_INADEQUATE_FOR_CONTENT_LENGTH = "BlobTierInadequateForContentLength"
+ BLOB_USES_CUSTOMER_SPECIFIED_ENCRYPTION = "BlobUsesCustomerSpecifiedEncryption"
+ BLOCK_COUNT_EXCEEDS_LIMIT = "BlockCountExceedsLimit"
+ BLOCK_LIST_TOO_LONG = "BlockListTooLong"
+ CANNOT_CHANGE_TO_LOWER_TIER = "CannotChangeToLowerTier"
+ CANNOT_VERIFY_COPY_SOURCE = "CannotVerifyCopySource"
+ CONTAINER_ALREADY_EXISTS = "ContainerAlreadyExists"
+ CONTAINER_BEING_DELETED = "ContainerBeingDeleted"
+ CONTAINER_DISABLED = "ContainerDisabled"
+ CONTAINER_NOT_FOUND = "ContainerNotFound"
+ CONTENT_LENGTH_LARGER_THAN_TIER_LIMIT = "ContentLengthLargerThanTierLimit"
+ COPY_ACROSS_ACCOUNTS_NOT_SUPPORTED = "CopyAcrossAccountsNotSupported"
+ COPY_ID_MISMATCH = "CopyIdMismatch"
+ FEATURE_VERSION_MISMATCH = "FeatureVersionMismatch"
+ INCREMENTAL_COPY_BLOB_MISMATCH = "IncrementalCopyBlobMismatch"
+ INCREMENTAL_COPY_OF_ERALIER_VERSION_SNAPSHOT_NOT_ALLOWED = "IncrementalCopyOfEralierVersionSnapshotNotAllowed"
+ INCREMENTAL_COPY_SOURCE_MUST_BE_SNAPSHOT = "IncrementalCopySourceMustBeSnapshot"
+ INFINITE_LEASE_DURATION_REQUIRED = "InfiniteLeaseDurationRequired"
+ INVALID_BLOB_OR_BLOCK = "InvalidBlobOrBlock"
+ INVALID_BLOB_TIER = "InvalidBlobTier"
+ INVALID_BLOB_TYPE = "InvalidBlobType"
+ INVALID_BLOCK_ID = "InvalidBlockId"
+ INVALID_BLOCK_LIST = "InvalidBlockList"
+ INVALID_OPERATION = "InvalidOperation"
+ INVALID_PAGE_RANGE = "InvalidPageRange"
+ INVALID_SOURCE_BLOB_TYPE = "InvalidSourceBlobType"
+ INVALID_SOURCE_BLOB_URL = "InvalidSourceBlobUrl"
+ INVALID_VERSION_FOR_PAGE_BLOB_OPERATION = "InvalidVersionForPageBlobOperation"
+ LEASE_ALREADY_PRESENT = "LeaseAlreadyPresent"
+ LEASE_ALREADY_BROKEN = "LeaseAlreadyBroken"
+ LEASE_ID_MISMATCH_WITH_BLOB_OPERATION = "LeaseIdMismatchWithBlobOperation"
+ LEASE_ID_MISMATCH_WITH_CONTAINER_OPERATION = "LeaseIdMismatchWithContainerOperation"
+ LEASE_ID_MISMATCH_WITH_LEASE_OPERATION = "LeaseIdMismatchWithLeaseOperation"
+ LEASE_ID_MISSING = "LeaseIdMissing"
+ LEASE_IS_BREAKING_AND_CANNOT_BE_ACQUIRED = "LeaseIsBreakingAndCannotBeAcquired"
+ LEASE_IS_BREAKING_AND_CANNOT_BE_CHANGED = "LeaseIsBreakingAndCannotBeChanged"
+ LEASE_IS_BROKEN_AND_CANNOT_BE_RENEWED = "LeaseIsBrokenAndCannotBeRenewed"
+ LEASE_LOST = "LeaseLost"
+ LEASE_NOT_PRESENT_WITH_BLOB_OPERATION = "LeaseNotPresentWithBlobOperation"
+ LEASE_NOT_PRESENT_WITH_CONTAINER_OPERATION = "LeaseNotPresentWithContainerOperation"
+ LEASE_NOT_PRESENT_WITH_LEASE_OPERATION = "LeaseNotPresentWithLeaseOperation"
+ MAX_BLOB_SIZE_CONDITION_NOT_MET = "MaxBlobSizeConditionNotMet"
+ NO_AUTHENTICATION_INFORMATION = "NoAuthenticationInformation"
+ NO_PENDING_COPY_OPERATION = "NoPendingCopyOperation"
+ OPERATION_NOT_ALLOWED_ON_INCREMENTAL_COPY_BLOB = "OperationNotAllowedOnIncrementalCopyBlob"
+ PENDING_COPY_OPERATION = "PendingCopyOperation"
+ PREVIOUS_SNAPSHOT_CANNOT_BE_NEWER = "PreviousSnapshotCannotBeNewer"
+ PREVIOUS_SNAPSHOT_NOT_FOUND = "PreviousSnapshotNotFound"
+ PREVIOUS_SNAPSHOT_OPERATION_NOT_SUPPORTED = "PreviousSnapshotOperationNotSupported"
+ SEQUENCE_NUMBER_CONDITION_NOT_MET = "SequenceNumberConditionNotMet"
+ SEQUENCE_NUMBER_INCREMENT_TOO_LARGE = "SequenceNumberIncrementTooLarge"
+ SNAPSHOT_COUNT_EXCEEDED = "SnapshotCountExceeded"
+ SNAPSHOT_OPERATION_RATE_EXCEEDED = "SnapshotOperationRateExceeded"
+ SNAPSHOTS_PRESENT = "SnapshotsPresent"
+ SOURCE_CONDITION_NOT_MET = "SourceConditionNotMet"
+ SYSTEM_IN_USE = "SystemInUse"
+ TARGET_CONDITION_NOT_MET = "TargetConditionNotMet"
+ UNAUTHORIZED_BLOB_OVERWRITE = "UnauthorizedBlobOverwrite"
+ BLOB_BEING_REHYDRATED = "BlobBeingRehydrated"
+ BLOB_ARCHIVED = "BlobArchived"
+ BLOB_NOT_ARCHIVED = "BlobNotArchived"
+ AUTHORIZATION_SOURCE_IP_MISMATCH = "AuthorizationSourceIPMismatch"
+ AUTHORIZATION_PROTOCOL_MISMATCH = "AuthorizationProtocolMismatch"
+ AUTHORIZATION_PERMISSION_MISMATCH = "AuthorizationPermissionMismatch"
+ AUTHORIZATION_SERVICE_MISMATCH = "AuthorizationServiceMismatch"
+ AUTHORIZATION_RESOURCE_TYPE_MISMATCH = "AuthorizationResourceTypeMismatch"
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_models.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_models.py
new file mode 100644
index 00000000000..abf16321bba
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_models.py
@@ -0,0 +1,1995 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from azure.core.exceptions import HttpResponseError
+import msrest.serialization
+
+
+class AccessPolicy(msrest.serialization.Model):
+ """An Access policy.
+
+ :param start: the date-time the policy is active.
+ :type start: str
+ :param expiry: the date-time the policy expires.
+ :type expiry: str
+ :param permission: the permissions for the acl policy.
+ :type permission: str
+ """
+
+ _attribute_map = {
+ 'start': {'key': 'Start', 'type': 'str'},
+ 'expiry': {'key': 'Expiry', 'type': 'str'},
+ 'permission': {'key': 'Permission', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(AccessPolicy, self).__init__(**kwargs)
+ self.start = kwargs.get('start', None)
+ self.expiry = kwargs.get('expiry', None)
+ self.permission = kwargs.get('permission', None)
+
+
+class AppendPositionAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param max_size: Optional conditional header. The max length in bytes permitted for the append
+ blob. If the Append Block operation would cause the blob to exceed that limit or if the blob
+ size is already greater than the value specified in this header, the request will fail with
+ MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed).
+ :type max_size: long
+ :param append_position: Optional conditional header, used only for the Append Block operation.
+ A number indicating the byte offset to compare. Append Block will succeed only if the append
+ position is equal to this number. If it is not, the request will fail with the
+ AppendPositionConditionNotMet error (HTTP status code 412 - Precondition Failed).
+ :type append_position: long
+ """
+
+ _attribute_map = {
+ 'max_size': {'key': 'maxSize', 'type': 'long'},
+ 'append_position': {'key': 'appendPosition', 'type': 'long'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(AppendPositionAccessConditions, self).__init__(**kwargs)
+ self.max_size = kwargs.get('max_size', None)
+ self.append_position = kwargs.get('append_position', None)
+
+
+class ArrowConfiguration(msrest.serialization.Model):
+ """Groups the settings used for formatting the response if the response should be Arrow formatted.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param schema: Required.
+ :type schema: list[~azure.storage.blob.models.ArrowField]
+ """
+
+ _validation = {
+ 'schema': {'required': True},
+ }
+
+ _attribute_map = {
+ 'schema': {'key': 'Schema', 'type': '[ArrowField]', 'xml': {'name': 'Schema', 'wrapped': True, 'itemsName': 'Field'}},
+ }
+ _xml_map = {
+ 'name': 'ArrowConfiguration'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ArrowConfiguration, self).__init__(**kwargs)
+ self.schema = kwargs['schema']
+
+
+class ArrowField(msrest.serialization.Model):
+ """Groups settings regarding specific field of an arrow schema.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param type: Required.
+ :type type: str
+ :param name:
+ :type name: str
+ :param precision:
+ :type precision: int
+ :param scale:
+ :type scale: int
+ """
+
+ _validation = {
+ 'type': {'required': True},
+ }
+
+ _attribute_map = {
+ 'type': {'key': 'Type', 'type': 'str'},
+ 'name': {'key': 'Name', 'type': 'str'},
+ 'precision': {'key': 'Precision', 'type': 'int'},
+ 'scale': {'key': 'Scale', 'type': 'int'},
+ }
+ _xml_map = {
+ 'name': 'Field'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ArrowField, self).__init__(**kwargs)
+ self.type = kwargs['type']
+ self.name = kwargs.get('name', None)
+ self.precision = kwargs.get('precision', None)
+ self.scale = kwargs.get('scale', None)
+
+
+class BlobFlatListSegment(msrest.serialization.Model):
+ """BlobFlatListSegment.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param blob_items: Required.
+ :type blob_items: list[~azure.storage.blob.models.BlobItemInternal]
+ """
+
+ _validation = {
+ 'blob_items': {'required': True},
+ }
+
+ _attribute_map = {
+ 'blob_items': {'key': 'BlobItems', 'type': '[BlobItemInternal]'},
+ }
+ _xml_map = {
+ 'name': 'Blobs'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobFlatListSegment, self).__init__(**kwargs)
+ self.blob_items = kwargs['blob_items']
+
+
+class BlobHierarchyListSegment(msrest.serialization.Model):
+ """BlobHierarchyListSegment.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param blob_prefixes:
+ :type blob_prefixes: list[~azure.storage.blob.models.BlobPrefix]
+ :param blob_items: Required.
+ :type blob_items: list[~azure.storage.blob.models.BlobItemInternal]
+ """
+
+ _validation = {
+ 'blob_items': {'required': True},
+ }
+
+ _attribute_map = {
+ 'blob_prefixes': {'key': 'BlobPrefixes', 'type': '[BlobPrefix]', 'xml': {'name': 'BlobPrefix'}},
+ 'blob_items': {'key': 'BlobItems', 'type': '[BlobItemInternal]', 'xml': {'name': 'Blob', 'itemsName': 'Blob'}},
+ }
+ _xml_map = {
+ 'name': 'Blobs'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobHierarchyListSegment, self).__init__(**kwargs)
+ self.blob_prefixes = kwargs.get('blob_prefixes', None)
+ self.blob_items = kwargs['blob_items']
+
+
+class BlobHTTPHeaders(msrest.serialization.Model):
+ """Parameter group.
+
+ :param blob_cache_control: Optional. Sets the blob's cache control. If specified, this property
+ is stored with the blob and returned with a read request.
+ :type blob_cache_control: str
+ :param blob_content_type: Optional. Sets the blob's content type. If specified, this property
+ is stored with the blob and returned with a read request.
+ :type blob_content_type: str
+ :param blob_content_md5: Optional. An MD5 hash of the blob content. Note that this hash is not
+ validated, as the hashes for the individual blocks were validated when each was uploaded.
+ :type blob_content_md5: bytearray
+ :param blob_content_encoding: Optional. Sets the blob's content encoding. If specified, this
+ property is stored with the blob and returned with a read request.
+ :type blob_content_encoding: str
+ :param blob_content_language: Optional. Set the blob's content language. If specified, this
+ property is stored with the blob and returned with a read request.
+ :type blob_content_language: str
+ :param blob_content_disposition: Optional. Sets the blob's Content-Disposition header.
+ :type blob_content_disposition: str
+ """
+
+ _attribute_map = {
+ 'blob_cache_control': {'key': 'blobCacheControl', 'type': 'str'},
+ 'blob_content_type': {'key': 'blobContentType', 'type': 'str'},
+ 'blob_content_md5': {'key': 'blobContentMD5', 'type': 'bytearray'},
+ 'blob_content_encoding': {'key': 'blobContentEncoding', 'type': 'str'},
+ 'blob_content_language': {'key': 'blobContentLanguage', 'type': 'str'},
+ 'blob_content_disposition': {'key': 'blobContentDisposition', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobHTTPHeaders, self).__init__(**kwargs)
+ self.blob_cache_control = kwargs.get('blob_cache_control', None)
+ self.blob_content_type = kwargs.get('blob_content_type', None)
+ self.blob_content_md5 = kwargs.get('blob_content_md5', None)
+ self.blob_content_encoding = kwargs.get('blob_content_encoding', None)
+ self.blob_content_language = kwargs.get('blob_content_language', None)
+ self.blob_content_disposition = kwargs.get('blob_content_disposition', None)
+
+
+class BlobItemInternal(msrest.serialization.Model):
+ """An Azure Storage blob.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required.
+ :type name: ~azure.storage.blob.models.BlobName
+ :param deleted: Required.
+ :type deleted: bool
+ :param snapshot: Required.
+ :type snapshot: str
+ :param version_id:
+ :type version_id: str
+ :param is_current_version:
+ :type is_current_version: bool
+ :param properties: Required. Properties of a blob.
+ :type properties: ~azure.storage.blob.models.BlobPropertiesInternal
+ :param metadata:
+ :type metadata: ~azure.storage.blob.models.BlobMetadata
+ :param blob_tags: Blob tags.
+ :type blob_tags: ~azure.storage.blob.models.BlobTags
+ :param has_versions_only:
+ :type has_versions_only: bool
+ :param object_replication_metadata: Dictionary of :code:``.
+ :type object_replication_metadata: dict[str, str]
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ 'deleted': {'required': True},
+ 'snapshot': {'required': True},
+ 'properties': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'BlobName'},
+ 'deleted': {'key': 'Deleted', 'type': 'bool'},
+ 'snapshot': {'key': 'Snapshot', 'type': 'str'},
+ 'version_id': {'key': 'VersionId', 'type': 'str'},
+ 'is_current_version': {'key': 'IsCurrentVersion', 'type': 'bool'},
+ 'properties': {'key': 'Properties', 'type': 'BlobPropertiesInternal'},
+ 'metadata': {'key': 'Metadata', 'type': 'BlobMetadata'},
+ 'blob_tags': {'key': 'BlobTags', 'type': 'BlobTags'},
+ 'has_versions_only': {'key': 'HasVersionsOnly', 'type': 'bool'},
+ 'object_replication_metadata': {'key': 'OrMetadata', 'type': '{str}'},
+ }
+ _xml_map = {
+ 'name': 'Blob'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobItemInternal, self).__init__(**kwargs)
+ self.name = kwargs['name']
+ self.deleted = kwargs['deleted']
+ self.snapshot = kwargs['snapshot']
+ self.version_id = kwargs.get('version_id', None)
+ self.is_current_version = kwargs.get('is_current_version', None)
+ self.properties = kwargs['properties']
+ self.metadata = kwargs.get('metadata', None)
+ self.blob_tags = kwargs.get('blob_tags', None)
+ self.has_versions_only = kwargs.get('has_versions_only', None)
+ self.object_replication_metadata = kwargs.get('object_replication_metadata', None)
+
+
+class BlobMetadata(msrest.serialization.Model):
+ """BlobMetadata.
+
+ :param additional_properties: Unmatched properties from the message are deserialized to this
+ collection.
+ :type additional_properties: dict[str, str]
+ :param encrypted:
+ :type encrypted: str
+ """
+
+ _attribute_map = {
+ 'additional_properties': {'key': '', 'type': '{str}'},
+ 'encrypted': {'key': 'Encrypted', 'type': 'str', 'xml': {'attr': True}},
+ }
+ _xml_map = {
+ 'name': 'Metadata'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobMetadata, self).__init__(**kwargs)
+ self.additional_properties = kwargs.get('additional_properties', None)
+ self.encrypted = kwargs.get('encrypted', None)
+
+
+class BlobName(msrest.serialization.Model):
+ """BlobName.
+
+ :param encoded: Indicates if the blob name is encoded.
+ :type encoded: bool
+ :param content: The name of the blob.
+ :type content: str
+ """
+
+ _attribute_map = {
+ 'encoded': {'key': 'Encoded', 'type': 'bool', 'xml': {'name': 'Encoded', 'attr': True}},
+ 'content': {'key': 'content', 'type': 'str', 'xml': {'text': True}},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobName, self).__init__(**kwargs)
+ self.encoded = kwargs.get('encoded', None)
+ self.content = kwargs.get('content', None)
+
+
+class BlobPrefix(msrest.serialization.Model):
+ """BlobPrefix.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required.
+ :type name: ~azure.storage.blob.models.BlobName
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'BlobName'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobPrefix, self).__init__(**kwargs)
+ self.name = kwargs['name']
+
+
+class BlobPropertiesInternal(msrest.serialization.Model):
+ """Properties of a blob.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param creation_time:
+ :type creation_time: ~datetime.datetime
+ :param last_modified: Required.
+ :type last_modified: ~datetime.datetime
+ :param etag: Required.
+ :type etag: str
+ :param content_length: Size in bytes.
+ :type content_length: long
+ :param content_type:
+ :type content_type: str
+ :param content_encoding:
+ :type content_encoding: str
+ :param content_language:
+ :type content_language: str
+ :param content_md5:
+ :type content_md5: bytearray
+ :param content_disposition:
+ :type content_disposition: str
+ :param cache_control:
+ :type cache_control: str
+ :param blob_sequence_number:
+ :type blob_sequence_number: long
+ :param blob_type: Possible values include: "BlockBlob", "PageBlob", "AppendBlob".
+ :type blob_type: str or ~azure.storage.blob.models.BlobType
+ :param lease_status: Possible values include: "locked", "unlocked".
+ :type lease_status: str or ~azure.storage.blob.models.LeaseStatusType
+ :param lease_state: Possible values include: "available", "leased", "expired", "breaking",
+ "broken".
+ :type lease_state: str or ~azure.storage.blob.models.LeaseStateType
+ :param lease_duration: Possible values include: "infinite", "fixed".
+ :type lease_duration: str or ~azure.storage.blob.models.LeaseDurationType
+ :param copy_id:
+ :type copy_id: str
+ :param copy_status: Possible values include: "pending", "success", "aborted", "failed".
+ :type copy_status: str or ~azure.storage.blob.models.CopyStatusType
+ :param copy_source:
+ :type copy_source: str
+ :param copy_progress:
+ :type copy_progress: str
+ :param copy_completion_time:
+ :type copy_completion_time: ~datetime.datetime
+ :param copy_status_description:
+ :type copy_status_description: str
+ :param server_encrypted:
+ :type server_encrypted: bool
+ :param incremental_copy:
+ :type incremental_copy: bool
+ :param destination_snapshot:
+ :type destination_snapshot: str
+ :param deleted_time:
+ :type deleted_time: ~datetime.datetime
+ :param remaining_retention_days:
+ :type remaining_retention_days: int
+ :param access_tier: Possible values include: "P4", "P6", "P10", "P15", "P20", "P30", "P40",
+ "P50", "P60", "P70", "P80", "Hot", "Cool", "Archive".
+ :type access_tier: str or ~azure.storage.blob.models.AccessTier
+ :param access_tier_inferred:
+ :type access_tier_inferred: bool
+ :param archive_status: Possible values include: "rehydrate-pending-to-hot",
+ "rehydrate-pending-to-cool".
+ :type archive_status: str or ~azure.storage.blob.models.ArchiveStatus
+ :param customer_provided_key_sha256:
+ :type customer_provided_key_sha256: str
+ :param encryption_scope: The name of the encryption scope under which the blob is encrypted.
+ :type encryption_scope: str
+ :param access_tier_change_time:
+ :type access_tier_change_time: ~datetime.datetime
+ :param tag_count:
+ :type tag_count: int
+ :param expires_on:
+ :type expires_on: ~datetime.datetime
+ :param is_sealed:
+ :type is_sealed: bool
+ :param rehydrate_priority: If an object is in rehydrate pending state then this header is
+ returned with priority of rehydrate. Valid values are High and Standard. Possible values
+ include: "High", "Standard".
+ :type rehydrate_priority: str or ~azure.storage.blob.models.RehydratePriority
+ :param last_accessed_on:
+ :type last_accessed_on: ~datetime.datetime
+ :param immutability_policy_expires_on:
+ :type immutability_policy_expires_on: ~datetime.datetime
+ :param immutability_policy_mode: Possible values include: "Mutable", "Unlocked", "Locked".
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold:
+ :type legal_hold: bool
+ """
+
+ _validation = {
+ 'last_modified': {'required': True},
+ 'etag': {'required': True},
+ }
+
+ _attribute_map = {
+ 'creation_time': {'key': 'Creation-Time', 'type': 'rfc-1123'},
+ 'last_modified': {'key': 'Last-Modified', 'type': 'rfc-1123'},
+ 'etag': {'key': 'Etag', 'type': 'str'},
+ 'content_length': {'key': 'Content-Length', 'type': 'long'},
+ 'content_type': {'key': 'Content-Type', 'type': 'str'},
+ 'content_encoding': {'key': 'Content-Encoding', 'type': 'str'},
+ 'content_language': {'key': 'Content-Language', 'type': 'str'},
+ 'content_md5': {'key': 'Content-MD5', 'type': 'bytearray'},
+ 'content_disposition': {'key': 'Content-Disposition', 'type': 'str'},
+ 'cache_control': {'key': 'Cache-Control', 'type': 'str'},
+ 'blob_sequence_number': {'key': 'x-ms-blob-sequence-number', 'type': 'long'},
+ 'blob_type': {'key': 'BlobType', 'type': 'str'},
+ 'lease_status': {'key': 'LeaseStatus', 'type': 'str'},
+ 'lease_state': {'key': 'LeaseState', 'type': 'str'},
+ 'lease_duration': {'key': 'LeaseDuration', 'type': 'str'},
+ 'copy_id': {'key': 'CopyId', 'type': 'str'},
+ 'copy_status': {'key': 'CopyStatus', 'type': 'str'},
+ 'copy_source': {'key': 'CopySource', 'type': 'str'},
+ 'copy_progress': {'key': 'CopyProgress', 'type': 'str'},
+ 'copy_completion_time': {'key': 'CopyCompletionTime', 'type': 'rfc-1123'},
+ 'copy_status_description': {'key': 'CopyStatusDescription', 'type': 'str'},
+ 'server_encrypted': {'key': 'ServerEncrypted', 'type': 'bool'},
+ 'incremental_copy': {'key': 'IncrementalCopy', 'type': 'bool'},
+ 'destination_snapshot': {'key': 'DestinationSnapshot', 'type': 'str'},
+ 'deleted_time': {'key': 'DeletedTime', 'type': 'rfc-1123'},
+ 'remaining_retention_days': {'key': 'RemainingRetentionDays', 'type': 'int'},
+ 'access_tier': {'key': 'AccessTier', 'type': 'str'},
+ 'access_tier_inferred': {'key': 'AccessTierInferred', 'type': 'bool'},
+ 'archive_status': {'key': 'ArchiveStatus', 'type': 'str'},
+ 'customer_provided_key_sha256': {'key': 'CustomerProvidedKeySha256', 'type': 'str'},
+ 'encryption_scope': {'key': 'EncryptionScope', 'type': 'str'},
+ 'access_tier_change_time': {'key': 'AccessTierChangeTime', 'type': 'rfc-1123'},
+ 'tag_count': {'key': 'TagCount', 'type': 'int'},
+ 'expires_on': {'key': 'Expiry-Time', 'type': 'rfc-1123'},
+ 'is_sealed': {'key': 'Sealed', 'type': 'bool'},
+ 'rehydrate_priority': {'key': 'RehydratePriority', 'type': 'str'},
+ 'last_accessed_on': {'key': 'LastAccessTime', 'type': 'rfc-1123'},
+ 'immutability_policy_expires_on': {'key': 'ImmutabilityPolicyUntilDate', 'type': 'rfc-1123'},
+ 'immutability_policy_mode': {'key': 'ImmutabilityPolicyMode', 'type': 'str'},
+ 'legal_hold': {'key': 'LegalHold', 'type': 'bool'},
+ }
+ _xml_map = {
+ 'name': 'Properties'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobPropertiesInternal, self).__init__(**kwargs)
+ self.creation_time = kwargs.get('creation_time', None)
+ self.last_modified = kwargs['last_modified']
+ self.etag = kwargs['etag']
+ self.content_length = kwargs.get('content_length', None)
+ self.content_type = kwargs.get('content_type', None)
+ self.content_encoding = kwargs.get('content_encoding', None)
+ self.content_language = kwargs.get('content_language', None)
+ self.content_md5 = kwargs.get('content_md5', None)
+ self.content_disposition = kwargs.get('content_disposition', None)
+ self.cache_control = kwargs.get('cache_control', None)
+ self.blob_sequence_number = kwargs.get('blob_sequence_number', None)
+ self.blob_type = kwargs.get('blob_type', None)
+ self.lease_status = kwargs.get('lease_status', None)
+ self.lease_state = kwargs.get('lease_state', None)
+ self.lease_duration = kwargs.get('lease_duration', None)
+ self.copy_id = kwargs.get('copy_id', None)
+ self.copy_status = kwargs.get('copy_status', None)
+ self.copy_source = kwargs.get('copy_source', None)
+ self.copy_progress = kwargs.get('copy_progress', None)
+ self.copy_completion_time = kwargs.get('copy_completion_time', None)
+ self.copy_status_description = kwargs.get('copy_status_description', None)
+ self.server_encrypted = kwargs.get('server_encrypted', None)
+ self.incremental_copy = kwargs.get('incremental_copy', None)
+ self.destination_snapshot = kwargs.get('destination_snapshot', None)
+ self.deleted_time = kwargs.get('deleted_time', None)
+ self.remaining_retention_days = kwargs.get('remaining_retention_days', None)
+ self.access_tier = kwargs.get('access_tier', None)
+ self.access_tier_inferred = kwargs.get('access_tier_inferred', None)
+ self.archive_status = kwargs.get('archive_status', None)
+ self.customer_provided_key_sha256 = kwargs.get('customer_provided_key_sha256', None)
+ self.encryption_scope = kwargs.get('encryption_scope', None)
+ self.access_tier_change_time = kwargs.get('access_tier_change_time', None)
+ self.tag_count = kwargs.get('tag_count', None)
+ self.expires_on = kwargs.get('expires_on', None)
+ self.is_sealed = kwargs.get('is_sealed', None)
+ self.rehydrate_priority = kwargs.get('rehydrate_priority', None)
+ self.last_accessed_on = kwargs.get('last_accessed_on', None)
+ self.immutability_policy_expires_on = kwargs.get('immutability_policy_expires_on', None)
+ self.immutability_policy_mode = kwargs.get('immutability_policy_mode', None)
+ self.legal_hold = kwargs.get('legal_hold', None)
+
+
+class BlobTag(msrest.serialization.Model):
+ """BlobTag.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param key: Required.
+ :type key: str
+ :param value: Required.
+ :type value: str
+ """
+
+ _validation = {
+ 'key': {'required': True},
+ 'value': {'required': True},
+ }
+
+ _attribute_map = {
+ 'key': {'key': 'Key', 'type': 'str'},
+ 'value': {'key': 'Value', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'Tag'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobTag, self).__init__(**kwargs)
+ self.key = kwargs['key']
+ self.value = kwargs['value']
+
+
+class BlobTags(msrest.serialization.Model):
+ """Blob tags.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param blob_tag_set: Required.
+ :type blob_tag_set: list[~azure.storage.blob.models.BlobTag]
+ """
+
+ _validation = {
+ 'blob_tag_set': {'required': True},
+ }
+
+ _attribute_map = {
+ 'blob_tag_set': {'key': 'BlobTagSet', 'type': '[BlobTag]', 'xml': {'name': 'TagSet', 'wrapped': True, 'itemsName': 'Tag'}},
+ }
+ _xml_map = {
+ 'name': 'Tags'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlobTags, self).__init__(**kwargs)
+ self.blob_tag_set = kwargs['blob_tag_set']
+
+
+class Block(msrest.serialization.Model):
+ """Represents a single block in a block blob. It describes the block's ID and size.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required. The base64 encoded block ID.
+ :type name: str
+ :param size: Required. The block size in bytes.
+ :type size: long
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ 'size': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'str'},
+ 'size': {'key': 'Size', 'type': 'long'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(Block, self).__init__(**kwargs)
+ self.name = kwargs['name']
+ self.size = kwargs['size']
+
+
+class BlockList(msrest.serialization.Model):
+ """BlockList.
+
+ :param committed_blocks:
+ :type committed_blocks: list[~azure.storage.blob.models.Block]
+ :param uncommitted_blocks:
+ :type uncommitted_blocks: list[~azure.storage.blob.models.Block]
+ """
+
+ _attribute_map = {
+ 'committed_blocks': {'key': 'CommittedBlocks', 'type': '[Block]', 'xml': {'wrapped': True}},
+ 'uncommitted_blocks': {'key': 'UncommittedBlocks', 'type': '[Block]', 'xml': {'wrapped': True}},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlockList, self).__init__(**kwargs)
+ self.committed_blocks = kwargs.get('committed_blocks', None)
+ self.uncommitted_blocks = kwargs.get('uncommitted_blocks', None)
+
+
+class BlockLookupList(msrest.serialization.Model):
+ """BlockLookupList.
+
+ :param committed:
+ :type committed: list[str]
+ :param uncommitted:
+ :type uncommitted: list[str]
+ :param latest:
+ :type latest: list[str]
+ """
+
+ _attribute_map = {
+ 'committed': {'key': 'Committed', 'type': '[str]', 'xml': {'itemsName': 'Committed'}},
+ 'uncommitted': {'key': 'Uncommitted', 'type': '[str]', 'xml': {'itemsName': 'Uncommitted'}},
+ 'latest': {'key': 'Latest', 'type': '[str]', 'xml': {'itemsName': 'Latest'}},
+ }
+ _xml_map = {
+ 'name': 'BlockList'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(BlockLookupList, self).__init__(**kwargs)
+ self.committed = kwargs.get('committed', None)
+ self.uncommitted = kwargs.get('uncommitted', None)
+ self.latest = kwargs.get('latest', None)
+
+
+class ClearRange(msrest.serialization.Model):
+ """ClearRange.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param start: Required.
+ :type start: long
+ :param end: Required.
+ :type end: long
+ """
+
+ _validation = {
+ 'start': {'required': True},
+ 'end': {'required': True},
+ }
+
+ _attribute_map = {
+ 'start': {'key': 'Start', 'type': 'long', 'xml': {'name': 'Start'}},
+ 'end': {'key': 'End', 'type': 'long', 'xml': {'name': 'End'}},
+ }
+ _xml_map = {
+ 'name': 'ClearRange'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ClearRange, self).__init__(**kwargs)
+ self.start = kwargs['start']
+ self.end = kwargs['end']
+
+
+class ContainerCpkScopeInfo(msrest.serialization.Model):
+ """Parameter group.
+
+ :param default_encryption_scope: Optional. Version 2019-07-07 and later. Specifies the
+ default encryption scope to set on the container and use for all future writes.
+ :type default_encryption_scope: str
+ :param prevent_encryption_scope_override: Optional. Version 2019-07-07 and newer. If true,
+ prevents any request from specifying a different encryption scope than the scope set on the
+ container.
+ :type prevent_encryption_scope_override: bool
+ """
+
+ _attribute_map = {
+ 'default_encryption_scope': {'key': 'DefaultEncryptionScope', 'type': 'str'},
+ 'prevent_encryption_scope_override': {'key': 'PreventEncryptionScopeOverride', 'type': 'bool'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ContainerCpkScopeInfo, self).__init__(**kwargs)
+ self.default_encryption_scope = kwargs.get('default_encryption_scope', None)
+ self.prevent_encryption_scope_override = kwargs.get('prevent_encryption_scope_override', None)
+
+
+class ContainerItem(msrest.serialization.Model):
+ """An Azure Storage container.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required.
+ :type name: str
+ :param deleted:
+ :type deleted: bool
+ :param version:
+ :type version: str
+ :param properties: Required. Properties of a container.
+ :type properties: ~azure.storage.blob.models.ContainerProperties
+ :param metadata: Dictionary of :code:``.
+ :type metadata: dict[str, str]
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ 'properties': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'str'},
+ 'deleted': {'key': 'Deleted', 'type': 'bool'},
+ 'version': {'key': 'Version', 'type': 'str'},
+ 'properties': {'key': 'Properties', 'type': 'ContainerProperties'},
+ 'metadata': {'key': 'Metadata', 'type': '{str}'},
+ }
+ _xml_map = {
+ 'name': 'Container'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ContainerItem, self).__init__(**kwargs)
+ self.name = kwargs['name']
+ self.deleted = kwargs.get('deleted', None)
+ self.version = kwargs.get('version', None)
+ self.properties = kwargs['properties']
+ self.metadata = kwargs.get('metadata', None)
+
+
+class ContainerProperties(msrest.serialization.Model):
+ """Properties of a container.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param last_modified: Required.
+ :type last_modified: ~datetime.datetime
+ :param etag: Required.
+ :type etag: str
+ :param lease_status: Possible values include: "locked", "unlocked".
+ :type lease_status: str or ~azure.storage.blob.models.LeaseStatusType
+ :param lease_state: Possible values include: "available", "leased", "expired", "breaking",
+ "broken".
+ :type lease_state: str or ~azure.storage.blob.models.LeaseStateType
+ :param lease_duration: Possible values include: "infinite", "fixed".
+ :type lease_duration: str or ~azure.storage.blob.models.LeaseDurationType
+ :param public_access: Possible values include: "container", "blob".
+ :type public_access: str or ~azure.storage.blob.models.PublicAccessType
+ :param has_immutability_policy:
+ :type has_immutability_policy: bool
+ :param has_legal_hold:
+ :type has_legal_hold: bool
+ :param default_encryption_scope:
+ :type default_encryption_scope: str
+ :param prevent_encryption_scope_override:
+ :type prevent_encryption_scope_override: bool
+ :param deleted_time:
+ :type deleted_time: ~datetime.datetime
+ :param remaining_retention_days:
+ :type remaining_retention_days: int
+ :param is_immutable_storage_with_versioning_enabled: Indicates if version level worm is enabled
+ on this container.
+ :type is_immutable_storage_with_versioning_enabled: bool
+ """
+
+ _validation = {
+ 'last_modified': {'required': True},
+ 'etag': {'required': True},
+ }
+
+ _attribute_map = {
+ 'last_modified': {'key': 'Last-Modified', 'type': 'rfc-1123'},
+ 'etag': {'key': 'Etag', 'type': 'str'},
+ 'lease_status': {'key': 'LeaseStatus', 'type': 'str'},
+ 'lease_state': {'key': 'LeaseState', 'type': 'str'},
+ 'lease_duration': {'key': 'LeaseDuration', 'type': 'str'},
+ 'public_access': {'key': 'PublicAccess', 'type': 'str'},
+ 'has_immutability_policy': {'key': 'HasImmutabilityPolicy', 'type': 'bool'},
+ 'has_legal_hold': {'key': 'HasLegalHold', 'type': 'bool'},
+ 'default_encryption_scope': {'key': 'DefaultEncryptionScope', 'type': 'str'},
+ 'prevent_encryption_scope_override': {'key': 'DenyEncryptionScopeOverride', 'type': 'bool'},
+ 'deleted_time': {'key': 'DeletedTime', 'type': 'rfc-1123'},
+ 'remaining_retention_days': {'key': 'RemainingRetentionDays', 'type': 'int'},
+ 'is_immutable_storage_with_versioning_enabled': {'key': 'ImmutableStorageWithVersioningEnabled', 'type': 'bool'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ContainerProperties, self).__init__(**kwargs)
+ self.last_modified = kwargs['last_modified']
+ self.etag = kwargs['etag']
+ self.lease_status = kwargs.get('lease_status', None)
+ self.lease_state = kwargs.get('lease_state', None)
+ self.lease_duration = kwargs.get('lease_duration', None)
+ self.public_access = kwargs.get('public_access', None)
+ self.has_immutability_policy = kwargs.get('has_immutability_policy', None)
+ self.has_legal_hold = kwargs.get('has_legal_hold', None)
+ self.default_encryption_scope = kwargs.get('default_encryption_scope', None)
+ self.prevent_encryption_scope_override = kwargs.get('prevent_encryption_scope_override', None)
+ self.deleted_time = kwargs.get('deleted_time', None)
+ self.remaining_retention_days = kwargs.get('remaining_retention_days', None)
+ self.is_immutable_storage_with_versioning_enabled = kwargs.get('is_immutable_storage_with_versioning_enabled', None)
+
+
+class CorsRule(msrest.serialization.Model):
+ """CORS is an HTTP feature that enables a web application running under one domain to access resources in another domain. Web browsers implement a security restriction known as same-origin policy that prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain (the origin domain) to call APIs in another domain.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param allowed_origins: Required. The origin domains that are permitted to make a request
+ against the storage service via CORS. The origin domain is the domain from which the request
+ originates. Note that the origin must be an exact case-sensitive match with the origin that the
+ user age sends to the service. You can also use the wildcard character '*' to allow all origin
+ domains to make requests via CORS.
+ :type allowed_origins: str
+ :param allowed_methods: Required. The methods (HTTP request verbs) that the origin domain may
+ use for a CORS request. (comma separated).
+ :type allowed_methods: str
+ :param allowed_headers: Required. the request headers that the origin domain may specify on the
+ CORS request.
+ :type allowed_headers: str
+ :param exposed_headers: Required. The response headers that may be sent in the response to the
+ CORS request and exposed by the browser to the request issuer.
+ :type exposed_headers: str
+ :param max_age_in_seconds: Required. The maximum amount time that a browser should cache the
+ preflight OPTIONS request.
+ :type max_age_in_seconds: int
+ """
+
+ _validation = {
+ 'allowed_origins': {'required': True},
+ 'allowed_methods': {'required': True},
+ 'allowed_headers': {'required': True},
+ 'exposed_headers': {'required': True},
+ 'max_age_in_seconds': {'required': True, 'minimum': 0},
+ }
+
+ _attribute_map = {
+ 'allowed_origins': {'key': 'AllowedOrigins', 'type': 'str'},
+ 'allowed_methods': {'key': 'AllowedMethods', 'type': 'str'},
+ 'allowed_headers': {'key': 'AllowedHeaders', 'type': 'str'},
+ 'exposed_headers': {'key': 'ExposedHeaders', 'type': 'str'},
+ 'max_age_in_seconds': {'key': 'MaxAgeInSeconds', 'type': 'int'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(CorsRule, self).__init__(**kwargs)
+ self.allowed_origins = kwargs['allowed_origins']
+ self.allowed_methods = kwargs['allowed_methods']
+ self.allowed_headers = kwargs['allowed_headers']
+ self.exposed_headers = kwargs['exposed_headers']
+ self.max_age_in_seconds = kwargs['max_age_in_seconds']
+
+
+class CpkInfo(msrest.serialization.Model):
+ """Parameter group.
+
+ :param encryption_key: Optional. Specifies the encryption key to use to encrypt the data
+ provided in the request. If not specified, encryption is performed with the root account
+ encryption key. For more information, see Encryption at Rest for Azure Storage Services.
+ :type encryption_key: str
+ :param encryption_key_sha256: The SHA-256 hash of the provided encryption key. Must be provided
+ if the x-ms-encryption-key header is provided.
+ :type encryption_key_sha256: str
+ :param encryption_algorithm: The algorithm used to produce the encryption key hash. Currently,
+ the only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is
+ provided. Possible values include: "None", "AES256".
+ :type encryption_algorithm: str or ~azure.storage.blob.models.EncryptionAlgorithmType
+ """
+
+ _attribute_map = {
+ 'encryption_key': {'key': 'encryptionKey', 'type': 'str'},
+ 'encryption_key_sha256': {'key': 'encryptionKeySha256', 'type': 'str'},
+ 'encryption_algorithm': {'key': 'encryptionAlgorithm', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(CpkInfo, self).__init__(**kwargs)
+ self.encryption_key = kwargs.get('encryption_key', None)
+ self.encryption_key_sha256 = kwargs.get('encryption_key_sha256', None)
+ self.encryption_algorithm = kwargs.get('encryption_algorithm', None)
+
+
+class CpkScopeInfo(msrest.serialization.Model):
+ """Parameter group.
+
+ :param encryption_scope: Optional. Version 2019-07-07 and later. Specifies the name of the
+ encryption scope to use to encrypt the data provided in the request. If not specified,
+ encryption is performed with the default account encryption scope. For more information, see
+ Encryption at Rest for Azure Storage Services.
+ :type encryption_scope: str
+ """
+
+ _attribute_map = {
+ 'encryption_scope': {'key': 'encryptionScope', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(CpkScopeInfo, self).__init__(**kwargs)
+ self.encryption_scope = kwargs.get('encryption_scope', None)
+
+
+class DelimitedTextConfiguration(msrest.serialization.Model):
+ """Groups the settings used for interpreting the blob data if the blob is delimited text formatted.
+
+ :param column_separator: The string used to separate columns.
+ :type column_separator: str
+ :param field_quote: The string used to quote a specific field.
+ :type field_quote: str
+ :param record_separator: The string used to separate records.
+ :type record_separator: str
+ :param escape_char: The string used as an escape character.
+ :type escape_char: str
+ :param headers_present: Represents whether the data has headers.
+ :type headers_present: bool
+ """
+
+ _attribute_map = {
+ 'column_separator': {'key': 'ColumnSeparator', 'type': 'str', 'xml': {'name': 'ColumnSeparator'}},
+ 'field_quote': {'key': 'FieldQuote', 'type': 'str', 'xml': {'name': 'FieldQuote'}},
+ 'record_separator': {'key': 'RecordSeparator', 'type': 'str', 'xml': {'name': 'RecordSeparator'}},
+ 'escape_char': {'key': 'EscapeChar', 'type': 'str', 'xml': {'name': 'EscapeChar'}},
+ 'headers_present': {'key': 'HeadersPresent', 'type': 'bool', 'xml': {'name': 'HasHeaders'}},
+ }
+ _xml_map = {
+ 'name': 'DelimitedTextConfiguration'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(DelimitedTextConfiguration, self).__init__(**kwargs)
+ self.column_separator = kwargs.get('column_separator', None)
+ self.field_quote = kwargs.get('field_quote', None)
+ self.record_separator = kwargs.get('record_separator', None)
+ self.escape_char = kwargs.get('escape_char', None)
+ self.headers_present = kwargs.get('headers_present', None)
+
+
+class FilterBlobItem(msrest.serialization.Model):
+ """Blob info from a Filter Blobs API call.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required.
+ :type name: str
+ :param container_name: Required.
+ :type container_name: str
+ :param tags: A set of tags. Blob tags.
+ :type tags: ~azure.storage.blob.models.BlobTags
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ 'container_name': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'str'},
+ 'container_name': {'key': 'ContainerName', 'type': 'str'},
+ 'tags': {'key': 'Tags', 'type': 'BlobTags'},
+ }
+ _xml_map = {
+ 'name': 'Blob'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(FilterBlobItem, self).__init__(**kwargs)
+ self.name = kwargs['name']
+ self.container_name = kwargs['container_name']
+ self.tags = kwargs.get('tags', None)
+
+
+class FilterBlobSegment(msrest.serialization.Model):
+ """The result of a Filter Blobs API call.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param service_endpoint: Required.
+ :type service_endpoint: str
+ :param where: Required.
+ :type where: str
+ :param blobs: Required.
+ :type blobs: list[~azure.storage.blob.models.FilterBlobItem]
+ :param next_marker:
+ :type next_marker: str
+ """
+
+ _validation = {
+ 'service_endpoint': {'required': True},
+ 'where': {'required': True},
+ 'blobs': {'required': True},
+ }
+
+ _attribute_map = {
+ 'service_endpoint': {'key': 'ServiceEndpoint', 'type': 'str', 'xml': {'attr': True}},
+ 'where': {'key': 'Where', 'type': 'str'},
+ 'blobs': {'key': 'Blobs', 'type': '[FilterBlobItem]', 'xml': {'name': 'Blobs', 'wrapped': True, 'itemsName': 'Blob'}},
+ 'next_marker': {'key': 'NextMarker', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'EnumerationResults'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(FilterBlobSegment, self).__init__(**kwargs)
+ self.service_endpoint = kwargs['service_endpoint']
+ self.where = kwargs['where']
+ self.blobs = kwargs['blobs']
+ self.next_marker = kwargs.get('next_marker', None)
+
+
+class GeoReplication(msrest.serialization.Model):
+ """Geo-Replication information for the Secondary Storage Service.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param status: Required. The status of the secondary location. Possible values include: "live",
+ "bootstrap", "unavailable".
+ :type status: str or ~azure.storage.blob.models.GeoReplicationStatusType
+ :param last_sync_time: Required. A GMT date/time value, to the second. All primary writes
+ preceding this value are guaranteed to be available for read operations at the secondary.
+ Primary writes after this point in time may or may not be available for reads.
+ :type last_sync_time: ~datetime.datetime
+ """
+
+ _validation = {
+ 'status': {'required': True},
+ 'last_sync_time': {'required': True},
+ }
+
+ _attribute_map = {
+ 'status': {'key': 'Status', 'type': 'str'},
+ 'last_sync_time': {'key': 'LastSyncTime', 'type': 'rfc-1123'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(GeoReplication, self).__init__(**kwargs)
+ self.status = kwargs['status']
+ self.last_sync_time = kwargs['last_sync_time']
+
+
+class JsonTextConfiguration(msrest.serialization.Model):
+ """json text configuration.
+
+ :param record_separator: The string used to separate records.
+ :type record_separator: str
+ """
+
+ _attribute_map = {
+ 'record_separator': {'key': 'RecordSeparator', 'type': 'str', 'xml': {'name': 'RecordSeparator'}},
+ }
+ _xml_map = {
+ 'name': 'JsonTextConfiguration'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(JsonTextConfiguration, self).__init__(**kwargs)
+ self.record_separator = kwargs.get('record_separator', None)
+
+
+class KeyInfo(msrest.serialization.Model):
+ """Key information.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param start: Required. The date-time the key is active in ISO 8601 UTC time.
+ :type start: str
+ :param expiry: Required. The date-time the key expires in ISO 8601 UTC time.
+ :type expiry: str
+ """
+
+ _validation = {
+ 'start': {'required': True},
+ 'expiry': {'required': True},
+ }
+
+ _attribute_map = {
+ 'start': {'key': 'Start', 'type': 'str'},
+ 'expiry': {'key': 'Expiry', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(KeyInfo, self).__init__(**kwargs)
+ self.start = kwargs['start']
+ self.expiry = kwargs['expiry']
+
+
+class LeaseAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param lease_id: If specified, the operation only succeeds if the resource's lease is active
+ and matches this ID.
+ :type lease_id: str
+ """
+
+ _attribute_map = {
+ 'lease_id': {'key': 'leaseId', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(LeaseAccessConditions, self).__init__(**kwargs)
+ self.lease_id = kwargs.get('lease_id', None)
+
+
+class ListBlobsFlatSegmentResponse(msrest.serialization.Model):
+ """An enumeration of blobs.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param service_endpoint: Required.
+ :type service_endpoint: str
+ :param container_name: Required.
+ :type container_name: str
+ :param prefix:
+ :type prefix: str
+ :param marker:
+ :type marker: str
+ :param max_results:
+ :type max_results: int
+ :param segment: Required.
+ :type segment: ~azure.storage.blob.models.BlobFlatListSegment
+ :param next_marker:
+ :type next_marker: str
+ """
+
+ _validation = {
+ 'service_endpoint': {'required': True},
+ 'container_name': {'required': True},
+ 'segment': {'required': True},
+ }
+
+ _attribute_map = {
+ 'service_endpoint': {'key': 'ServiceEndpoint', 'type': 'str', 'xml': {'attr': True}},
+ 'container_name': {'key': 'ContainerName', 'type': 'str', 'xml': {'attr': True}},
+ 'prefix': {'key': 'Prefix', 'type': 'str'},
+ 'marker': {'key': 'Marker', 'type': 'str'},
+ 'max_results': {'key': 'MaxResults', 'type': 'int'},
+ 'segment': {'key': 'Segment', 'type': 'BlobFlatListSegment'},
+ 'next_marker': {'key': 'NextMarker', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'EnumerationResults'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ListBlobsFlatSegmentResponse, self).__init__(**kwargs)
+ self.service_endpoint = kwargs['service_endpoint']
+ self.container_name = kwargs['container_name']
+ self.prefix = kwargs.get('prefix', None)
+ self.marker = kwargs.get('marker', None)
+ self.max_results = kwargs.get('max_results', None)
+ self.segment = kwargs['segment']
+ self.next_marker = kwargs.get('next_marker', None)
+
+
+class ListBlobsHierarchySegmentResponse(msrest.serialization.Model):
+ """An enumeration of blobs.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param service_endpoint: Required.
+ :type service_endpoint: str
+ :param container_name: Required.
+ :type container_name: str
+ :param prefix:
+ :type prefix: str
+ :param marker:
+ :type marker: str
+ :param max_results:
+ :type max_results: int
+ :param delimiter:
+ :type delimiter: str
+ :param segment: Required.
+ :type segment: ~azure.storage.blob.models.BlobHierarchyListSegment
+ :param next_marker:
+ :type next_marker: str
+ """
+
+ _validation = {
+ 'service_endpoint': {'required': True},
+ 'container_name': {'required': True},
+ 'segment': {'required': True},
+ }
+
+ _attribute_map = {
+ 'service_endpoint': {'key': 'ServiceEndpoint', 'type': 'str', 'xml': {'attr': True}},
+ 'container_name': {'key': 'ContainerName', 'type': 'str', 'xml': {'attr': True}},
+ 'prefix': {'key': 'Prefix', 'type': 'str'},
+ 'marker': {'key': 'Marker', 'type': 'str'},
+ 'max_results': {'key': 'MaxResults', 'type': 'int'},
+ 'delimiter': {'key': 'Delimiter', 'type': 'str'},
+ 'segment': {'key': 'Segment', 'type': 'BlobHierarchyListSegment'},
+ 'next_marker': {'key': 'NextMarker', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'EnumerationResults'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ListBlobsHierarchySegmentResponse, self).__init__(**kwargs)
+ self.service_endpoint = kwargs['service_endpoint']
+ self.container_name = kwargs['container_name']
+ self.prefix = kwargs.get('prefix', None)
+ self.marker = kwargs.get('marker', None)
+ self.max_results = kwargs.get('max_results', None)
+ self.delimiter = kwargs.get('delimiter', None)
+ self.segment = kwargs['segment']
+ self.next_marker = kwargs.get('next_marker', None)
+
+
+class ListContainersSegmentResponse(msrest.serialization.Model):
+ """An enumeration of containers.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param service_endpoint: Required.
+ :type service_endpoint: str
+ :param prefix:
+ :type prefix: str
+ :param marker:
+ :type marker: str
+ :param max_results:
+ :type max_results: int
+ :param container_items: Required.
+ :type container_items: list[~azure.storage.blob.models.ContainerItem]
+ :param next_marker:
+ :type next_marker: str
+ """
+
+ _validation = {
+ 'service_endpoint': {'required': True},
+ 'container_items': {'required': True},
+ }
+
+ _attribute_map = {
+ 'service_endpoint': {'key': 'ServiceEndpoint', 'type': 'str', 'xml': {'attr': True}},
+ 'prefix': {'key': 'Prefix', 'type': 'str'},
+ 'marker': {'key': 'Marker', 'type': 'str'},
+ 'max_results': {'key': 'MaxResults', 'type': 'int'},
+ 'container_items': {'key': 'ContainerItems', 'type': '[ContainerItem]', 'xml': {'name': 'Containers', 'wrapped': True, 'itemsName': 'Container'}},
+ 'next_marker': {'key': 'NextMarker', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'EnumerationResults'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ListContainersSegmentResponse, self).__init__(**kwargs)
+ self.service_endpoint = kwargs['service_endpoint']
+ self.prefix = kwargs.get('prefix', None)
+ self.marker = kwargs.get('marker', None)
+ self.max_results = kwargs.get('max_results', None)
+ self.container_items = kwargs['container_items']
+ self.next_marker = kwargs.get('next_marker', None)
+
+
+class Logging(msrest.serialization.Model):
+ """Azure Analytics Logging settings.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param version: Required. The version of Storage Analytics to configure.
+ :type version: str
+ :param delete: Required. Indicates whether all delete requests should be logged.
+ :type delete: bool
+ :param read: Required. Indicates whether all read requests should be logged.
+ :type read: bool
+ :param write: Required. Indicates whether all write requests should be logged.
+ :type write: bool
+ :param retention_policy: Required. the retention policy which determines how long the
+ associated data should persist.
+ :type retention_policy: ~azure.storage.blob.models.RetentionPolicy
+ """
+
+ _validation = {
+ 'version': {'required': True},
+ 'delete': {'required': True},
+ 'read': {'required': True},
+ 'write': {'required': True},
+ 'retention_policy': {'required': True},
+ }
+
+ _attribute_map = {
+ 'version': {'key': 'Version', 'type': 'str'},
+ 'delete': {'key': 'Delete', 'type': 'bool'},
+ 'read': {'key': 'Read', 'type': 'bool'},
+ 'write': {'key': 'Write', 'type': 'bool'},
+ 'retention_policy': {'key': 'RetentionPolicy', 'type': 'RetentionPolicy'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(Logging, self).__init__(**kwargs)
+ self.version = kwargs['version']
+ self.delete = kwargs['delete']
+ self.read = kwargs['read']
+ self.write = kwargs['write']
+ self.retention_policy = kwargs['retention_policy']
+
+
+class Metrics(msrest.serialization.Model):
+ """a summary of request statistics grouped by API in hour or minute aggregates for blobs.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param version: The version of Storage Analytics to configure.
+ :type version: str
+ :param enabled: Required. Indicates whether metrics are enabled for the Blob service.
+ :type enabled: bool
+ :param include_apis: Indicates whether metrics should generate summary statistics for called
+ API operations.
+ :type include_apis: bool
+ :param retention_policy: the retention policy which determines how long the associated data
+ should persist.
+ :type retention_policy: ~azure.storage.blob.models.RetentionPolicy
+ """
+
+ _validation = {
+ 'enabled': {'required': True},
+ }
+
+ _attribute_map = {
+ 'version': {'key': 'Version', 'type': 'str'},
+ 'enabled': {'key': 'Enabled', 'type': 'bool'},
+ 'include_apis': {'key': 'IncludeAPIs', 'type': 'bool'},
+ 'retention_policy': {'key': 'RetentionPolicy', 'type': 'RetentionPolicy'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(Metrics, self).__init__(**kwargs)
+ self.version = kwargs.get('version', None)
+ self.enabled = kwargs['enabled']
+ self.include_apis = kwargs.get('include_apis', None)
+ self.retention_policy = kwargs.get('retention_policy', None)
+
+
+class ModifiedAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param if_modified_since: Specify this header value to operate only on a blob if it has been
+ modified since the specified date/time.
+ :type if_modified_since: ~datetime.datetime
+ :param if_unmodified_since: Specify this header value to operate only on a blob if it has not
+ been modified since the specified date/time.
+ :type if_unmodified_since: ~datetime.datetime
+ :param if_match: Specify an ETag value to operate only on blobs with a matching value.
+ :type if_match: str
+ :param if_none_match: Specify an ETag value to operate only on blobs without a matching value.
+ :type if_none_match: str
+ :param if_tags: Specify a SQL where clause on blob tags to operate only on blobs with a
+ matching value.
+ :type if_tags: str
+ """
+
+ _attribute_map = {
+ 'if_modified_since': {'key': 'ifModifiedSince', 'type': 'rfc-1123'},
+ 'if_unmodified_since': {'key': 'ifUnmodifiedSince', 'type': 'rfc-1123'},
+ 'if_match': {'key': 'ifMatch', 'type': 'str'},
+ 'if_none_match': {'key': 'ifNoneMatch', 'type': 'str'},
+ 'if_tags': {'key': 'ifTags', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(ModifiedAccessConditions, self).__init__(**kwargs)
+ self.if_modified_since = kwargs.get('if_modified_since', None)
+ self.if_unmodified_since = kwargs.get('if_unmodified_since', None)
+ self.if_match = kwargs.get('if_match', None)
+ self.if_none_match = kwargs.get('if_none_match', None)
+ self.if_tags = kwargs.get('if_tags', None)
+
+
+class PageList(msrest.serialization.Model):
+ """the list of pages.
+
+ :param page_range:
+ :type page_range: list[~azure.storage.blob.models.PageRange]
+ :param clear_range:
+ :type clear_range: list[~azure.storage.blob.models.ClearRange]
+ """
+
+ _attribute_map = {
+ 'page_range': {'key': 'PageRange', 'type': '[PageRange]'},
+ 'clear_range': {'key': 'ClearRange', 'type': '[ClearRange]'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(PageList, self).__init__(**kwargs)
+ self.page_range = kwargs.get('page_range', None)
+ self.clear_range = kwargs.get('clear_range', None)
+
+
+class PageRange(msrest.serialization.Model):
+ """PageRange.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param start: Required.
+ :type start: long
+ :param end: Required.
+ :type end: long
+ """
+
+ _validation = {
+ 'start': {'required': True},
+ 'end': {'required': True},
+ }
+
+ _attribute_map = {
+ 'start': {'key': 'Start', 'type': 'long', 'xml': {'name': 'Start'}},
+ 'end': {'key': 'End', 'type': 'long', 'xml': {'name': 'End'}},
+ }
+ _xml_map = {
+ 'name': 'PageRange'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(PageRange, self).__init__(**kwargs)
+ self.start = kwargs['start']
+ self.end = kwargs['end']
+
+
+class QueryFormat(msrest.serialization.Model):
+ """QueryFormat.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param type: Required. The quick query format type. Possible values include: "delimited",
+ "json", "arrow", "parquet".
+ :type type: str or ~azure.storage.blob.models.QueryFormatType
+ :param delimited_text_configuration: Groups the settings used for interpreting the blob data if
+ the blob is delimited text formatted.
+ :type delimited_text_configuration: ~azure.storage.blob.models.DelimitedTextConfiguration
+ :param json_text_configuration: json text configuration.
+ :type json_text_configuration: ~azure.storage.blob.models.JsonTextConfiguration
+ :param arrow_configuration: Groups the settings used for formatting the response if the
+ response should be Arrow formatted.
+ :type arrow_configuration: ~azure.storage.blob.models.ArrowConfiguration
+ :param parquet_text_configuration: Any object.
+ :type parquet_text_configuration: any
+ """
+
+ _validation = {
+ 'type': {'required': True},
+ }
+
+ _attribute_map = {
+ 'type': {'key': 'Type', 'type': 'str', 'xml': {'name': 'Type'}},
+ 'delimited_text_configuration': {'key': 'DelimitedTextConfiguration', 'type': 'DelimitedTextConfiguration'},
+ 'json_text_configuration': {'key': 'JsonTextConfiguration', 'type': 'JsonTextConfiguration'},
+ 'arrow_configuration': {'key': 'ArrowConfiguration', 'type': 'ArrowConfiguration'},
+ 'parquet_text_configuration': {'key': 'ParquetTextConfiguration', 'type': 'object'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(QueryFormat, self).__init__(**kwargs)
+ self.type = kwargs['type']
+ self.delimited_text_configuration = kwargs.get('delimited_text_configuration', None)
+ self.json_text_configuration = kwargs.get('json_text_configuration', None)
+ self.arrow_configuration = kwargs.get('arrow_configuration', None)
+ self.parquet_text_configuration = kwargs.get('parquet_text_configuration', None)
+
+
+class QueryRequest(msrest.serialization.Model):
+ """Groups the set of query request settings.
+
+ Variables are only populated by the server, and will be ignored when sending a request.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :ivar query_type: Required. The type of the provided query expression. Has constant value:
+ "SQL".
+ :vartype query_type: str
+ :param expression: Required. The query expression in SQL. The maximum size of the query
+ expression is 256KiB.
+ :type expression: str
+ :param input_serialization:
+ :type input_serialization: ~azure.storage.blob.models.QuerySerialization
+ :param output_serialization:
+ :type output_serialization: ~azure.storage.blob.models.QuerySerialization
+ """
+
+ _validation = {
+ 'query_type': {'required': True, 'constant': True},
+ 'expression': {'required': True},
+ }
+
+ _attribute_map = {
+ 'query_type': {'key': 'QueryType', 'type': 'str', 'xml': {'name': 'QueryType'}},
+ 'expression': {'key': 'Expression', 'type': 'str', 'xml': {'name': 'Expression'}},
+ 'input_serialization': {'key': 'InputSerialization', 'type': 'QuerySerialization'},
+ 'output_serialization': {'key': 'OutputSerialization', 'type': 'QuerySerialization'},
+ }
+ _xml_map = {
+ 'name': 'QueryRequest'
+ }
+
+ query_type = "SQL"
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(QueryRequest, self).__init__(**kwargs)
+ self.expression = kwargs['expression']
+ self.input_serialization = kwargs.get('input_serialization', None)
+ self.output_serialization = kwargs.get('output_serialization', None)
+
+
+class QuerySerialization(msrest.serialization.Model):
+ """QuerySerialization.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param format: Required.
+ :type format: ~azure.storage.blob.models.QueryFormat
+ """
+
+ _validation = {
+ 'format': {'required': True},
+ }
+
+ _attribute_map = {
+ 'format': {'key': 'Format', 'type': 'QueryFormat'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(QuerySerialization, self).__init__(**kwargs)
+ self.format = kwargs['format']
+
+
+class RetentionPolicy(msrest.serialization.Model):
+ """the retention policy which determines how long the associated data should persist.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param enabled: Required. Indicates whether a retention policy is enabled for the storage
+ service.
+ :type enabled: bool
+ :param days: Indicates the number of days that metrics or logging or soft-deleted data should
+ be retained. All data older than this value will be deleted.
+ :type days: int
+ :param allow_permanent_delete: Indicates whether permanent delete is allowed on this storage
+ account.
+ :type allow_permanent_delete: bool
+ """
+
+ _validation = {
+ 'enabled': {'required': True},
+ 'days': {'minimum': 1},
+ }
+
+ _attribute_map = {
+ 'enabled': {'key': 'Enabled', 'type': 'bool'},
+ 'days': {'key': 'Days', 'type': 'int'},
+ 'allow_permanent_delete': {'key': 'AllowPermanentDelete', 'type': 'bool'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(RetentionPolicy, self).__init__(**kwargs)
+ self.enabled = kwargs['enabled']
+ self.days = kwargs.get('days', None)
+ self.allow_permanent_delete = kwargs.get('allow_permanent_delete', None)
+
+
+class SequenceNumberAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param if_sequence_number_less_than_or_equal_to: Specify this header value to operate only on a
+ blob if it has a sequence number less than or equal to the specified.
+ :type if_sequence_number_less_than_or_equal_to: long
+ :param if_sequence_number_less_than: Specify this header value to operate only on a blob if it
+ has a sequence number less than the specified.
+ :type if_sequence_number_less_than: long
+ :param if_sequence_number_equal_to: Specify this header value to operate only on a blob if it
+ has the specified sequence number.
+ :type if_sequence_number_equal_to: long
+ """
+
+ _attribute_map = {
+ 'if_sequence_number_less_than_or_equal_to': {'key': 'ifSequenceNumberLessThanOrEqualTo', 'type': 'long'},
+ 'if_sequence_number_less_than': {'key': 'ifSequenceNumberLessThan', 'type': 'long'},
+ 'if_sequence_number_equal_to': {'key': 'ifSequenceNumberEqualTo', 'type': 'long'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(SequenceNumberAccessConditions, self).__init__(**kwargs)
+ self.if_sequence_number_less_than_or_equal_to = kwargs.get('if_sequence_number_less_than_or_equal_to', None)
+ self.if_sequence_number_less_than = kwargs.get('if_sequence_number_less_than', None)
+ self.if_sequence_number_equal_to = kwargs.get('if_sequence_number_equal_to', None)
+
+
+class SignedIdentifier(msrest.serialization.Model):
+ """signed identifier.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param id: Required. a unique id.
+ :type id: str
+ :param access_policy: An Access policy.
+ :type access_policy: ~azure.storage.blob.models.AccessPolicy
+ """
+
+ _validation = {
+ 'id': {'required': True},
+ }
+
+ _attribute_map = {
+ 'id': {'key': 'Id', 'type': 'str'},
+ 'access_policy': {'key': 'AccessPolicy', 'type': 'AccessPolicy'},
+ }
+ _xml_map = {
+ 'name': 'SignedIdentifier'
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(SignedIdentifier, self).__init__(**kwargs)
+ self.id = kwargs['id']
+ self.access_policy = kwargs.get('access_policy', None)
+
+
+class SourceModifiedAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param source_if_modified_since: Specify this header value to operate only on a blob if it has
+ been modified since the specified date/time.
+ :type source_if_modified_since: ~datetime.datetime
+ :param source_if_unmodified_since: Specify this header value to operate only on a blob if it
+ has not been modified since the specified date/time.
+ :type source_if_unmodified_since: ~datetime.datetime
+ :param source_if_match: Specify an ETag value to operate only on blobs with a matching value.
+ :type source_if_match: str
+ :param source_if_none_match: Specify an ETag value to operate only on blobs without a matching
+ value.
+ :type source_if_none_match: str
+ :param source_if_tags: Specify a SQL where clause on blob tags to operate only on blobs with a
+ matching value.
+ :type source_if_tags: str
+ """
+
+ _attribute_map = {
+ 'source_if_modified_since': {'key': 'sourceIfModifiedSince', 'type': 'rfc-1123'},
+ 'source_if_unmodified_since': {'key': 'sourceIfUnmodifiedSince', 'type': 'rfc-1123'},
+ 'source_if_match': {'key': 'sourceIfMatch', 'type': 'str'},
+ 'source_if_none_match': {'key': 'sourceIfNoneMatch', 'type': 'str'},
+ 'source_if_tags': {'key': 'sourceIfTags', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(SourceModifiedAccessConditions, self).__init__(**kwargs)
+ self.source_if_modified_since = kwargs.get('source_if_modified_since', None)
+ self.source_if_unmodified_since = kwargs.get('source_if_unmodified_since', None)
+ self.source_if_match = kwargs.get('source_if_match', None)
+ self.source_if_none_match = kwargs.get('source_if_none_match', None)
+ self.source_if_tags = kwargs.get('source_if_tags', None)
+
+
+class StaticWebsite(msrest.serialization.Model):
+ """The properties that enable an account to host a static website.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param enabled: Required. Indicates whether this account is hosting a static website.
+ :type enabled: bool
+ :param index_document: The default name of the index page under each directory.
+ :type index_document: str
+ :param error_document404_path: The absolute path of the custom 404 page.
+ :type error_document404_path: str
+ :param default_index_document_path: Absolute path of the default index page.
+ :type default_index_document_path: str
+ """
+
+ _validation = {
+ 'enabled': {'required': True},
+ }
+
+ _attribute_map = {
+ 'enabled': {'key': 'Enabled', 'type': 'bool'},
+ 'index_document': {'key': 'IndexDocument', 'type': 'str'},
+ 'error_document404_path': {'key': 'ErrorDocument404Path', 'type': 'str'},
+ 'default_index_document_path': {'key': 'DefaultIndexDocumentPath', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(StaticWebsite, self).__init__(**kwargs)
+ self.enabled = kwargs['enabled']
+ self.index_document = kwargs.get('index_document', None)
+ self.error_document404_path = kwargs.get('error_document404_path', None)
+ self.default_index_document_path = kwargs.get('default_index_document_path', None)
+
+
+class StorageError(msrest.serialization.Model):
+ """StorageError.
+
+ :param message:
+ :type message: str
+ """
+
+ _attribute_map = {
+ 'message': {'key': 'Message', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(StorageError, self).__init__(**kwargs)
+ self.message = kwargs.get('message', None)
+
+
+class StorageServiceProperties(msrest.serialization.Model):
+ """Storage Service Properties.
+
+ :param logging: Azure Analytics Logging settings.
+ :type logging: ~azure.storage.blob.models.Logging
+ :param hour_metrics: a summary of request statistics grouped by API in hour or minute
+ aggregates for blobs.
+ :type hour_metrics: ~azure.storage.blob.models.Metrics
+ :param minute_metrics: a summary of request statistics grouped by API in hour or minute
+ aggregates for blobs.
+ :type minute_metrics: ~azure.storage.blob.models.Metrics
+ :param cors: The set of CORS rules.
+ :type cors: list[~azure.storage.blob.models.CorsRule]
+ :param default_service_version: The default version to use for requests to the Blob service if
+ an incoming request's version is not specified. Possible values include version 2008-10-27 and
+ all more recent versions.
+ :type default_service_version: str
+ :param delete_retention_policy: the retention policy which determines how long the associated
+ data should persist.
+ :type delete_retention_policy: ~azure.storage.blob.models.RetentionPolicy
+ :param static_website: The properties that enable an account to host a static website.
+ :type static_website: ~azure.storage.blob.models.StaticWebsite
+ """
+
+ _attribute_map = {
+ 'logging': {'key': 'Logging', 'type': 'Logging'},
+ 'hour_metrics': {'key': 'HourMetrics', 'type': 'Metrics'},
+ 'minute_metrics': {'key': 'MinuteMetrics', 'type': 'Metrics'},
+ 'cors': {'key': 'Cors', 'type': '[CorsRule]', 'xml': {'wrapped': True}},
+ 'default_service_version': {'key': 'DefaultServiceVersion', 'type': 'str'},
+ 'delete_retention_policy': {'key': 'DeleteRetentionPolicy', 'type': 'RetentionPolicy'},
+ 'static_website': {'key': 'StaticWebsite', 'type': 'StaticWebsite'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(StorageServiceProperties, self).__init__(**kwargs)
+ self.logging = kwargs.get('logging', None)
+ self.hour_metrics = kwargs.get('hour_metrics', None)
+ self.minute_metrics = kwargs.get('minute_metrics', None)
+ self.cors = kwargs.get('cors', None)
+ self.default_service_version = kwargs.get('default_service_version', None)
+ self.delete_retention_policy = kwargs.get('delete_retention_policy', None)
+ self.static_website = kwargs.get('static_website', None)
+
+
+class StorageServiceStats(msrest.serialization.Model):
+ """Stats for the storage service.
+
+ :param geo_replication: Geo-Replication information for the Secondary Storage Service.
+ :type geo_replication: ~azure.storage.blob.models.GeoReplication
+ """
+
+ _attribute_map = {
+ 'geo_replication': {'key': 'GeoReplication', 'type': 'GeoReplication'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(StorageServiceStats, self).__init__(**kwargs)
+ self.geo_replication = kwargs.get('geo_replication', None)
+
+
+class UserDelegationKey(msrest.serialization.Model):
+ """A user delegation key.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param signed_oid: Required. The Azure Active Directory object ID in GUID format.
+ :type signed_oid: str
+ :param signed_tid: Required. The Azure Active Directory tenant ID in GUID format.
+ :type signed_tid: str
+ :param signed_start: Required. The date-time the key is active.
+ :type signed_start: ~datetime.datetime
+ :param signed_expiry: Required. The date-time the key expires.
+ :type signed_expiry: ~datetime.datetime
+ :param signed_service: Required. Abbreviation of the Azure Storage service that accepts the
+ key.
+ :type signed_service: str
+ :param signed_version: Required. The service version that created the key.
+ :type signed_version: str
+ :param value: Required. The key as a base64 string.
+ :type value: str
+ """
+
+ _validation = {
+ 'signed_oid': {'required': True},
+ 'signed_tid': {'required': True},
+ 'signed_start': {'required': True},
+ 'signed_expiry': {'required': True},
+ 'signed_service': {'required': True},
+ 'signed_version': {'required': True},
+ 'value': {'required': True},
+ }
+
+ _attribute_map = {
+ 'signed_oid': {'key': 'SignedOid', 'type': 'str'},
+ 'signed_tid': {'key': 'SignedTid', 'type': 'str'},
+ 'signed_start': {'key': 'SignedStart', 'type': 'iso-8601'},
+ 'signed_expiry': {'key': 'SignedExpiry', 'type': 'iso-8601'},
+ 'signed_service': {'key': 'SignedService', 'type': 'str'},
+ 'signed_version': {'key': 'SignedVersion', 'type': 'str'},
+ 'value': {'key': 'Value', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ **kwargs
+ ):
+ super(UserDelegationKey, self).__init__(**kwargs)
+ self.signed_oid = kwargs['signed_oid']
+ self.signed_tid = kwargs['signed_tid']
+ self.signed_start = kwargs['signed_start']
+ self.signed_expiry = kwargs['signed_expiry']
+ self.signed_service = kwargs['signed_service']
+ self.signed_version = kwargs['signed_version']
+ self.value = kwargs['value']
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_models_py3.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_models_py3.py
new file mode 100644
index 00000000000..e51ab85be0c
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/models/_models_py3.py
@@ -0,0 +1,2265 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+import datetime
+from typing import Any, Dict, List, Optional, Union
+
+from azure.core.exceptions import HttpResponseError
+import msrest.serialization
+
+from ._azure_blob_storage_enums import *
+
+
+class AccessPolicy(msrest.serialization.Model):
+ """An Access policy.
+
+ :param start: the date-time the policy is active.
+ :type start: str
+ :param expiry: the date-time the policy expires.
+ :type expiry: str
+ :param permission: the permissions for the acl policy.
+ :type permission: str
+ """
+
+ _attribute_map = {
+ 'start': {'key': 'Start', 'type': 'str'},
+ 'expiry': {'key': 'Expiry', 'type': 'str'},
+ 'permission': {'key': 'Permission', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ start: Optional[str] = None,
+ expiry: Optional[str] = None,
+ permission: Optional[str] = None,
+ **kwargs
+ ):
+ super(AccessPolicy, self).__init__(**kwargs)
+ self.start = start
+ self.expiry = expiry
+ self.permission = permission
+
+
+class AppendPositionAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param max_size: Optional conditional header. The max length in bytes permitted for the append
+ blob. If the Append Block operation would cause the blob to exceed that limit or if the blob
+ size is already greater than the value specified in this header, the request will fail with
+ MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed).
+ :type max_size: long
+ :param append_position: Optional conditional header, used only for the Append Block operation.
+ A number indicating the byte offset to compare. Append Block will succeed only if the append
+ position is equal to this number. If it is not, the request will fail with the
+ AppendPositionConditionNotMet error (HTTP status code 412 - Precondition Failed).
+ :type append_position: long
+ """
+
+ _attribute_map = {
+ 'max_size': {'key': 'maxSize', 'type': 'long'},
+ 'append_position': {'key': 'appendPosition', 'type': 'long'},
+ }
+
+ def __init__(
+ self,
+ *,
+ max_size: Optional[int] = None,
+ append_position: Optional[int] = None,
+ **kwargs
+ ):
+ super(AppendPositionAccessConditions, self).__init__(**kwargs)
+ self.max_size = max_size
+ self.append_position = append_position
+
+
+class ArrowConfiguration(msrest.serialization.Model):
+ """Groups the settings used for formatting the response if the response should be Arrow formatted.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param schema: Required.
+ :type schema: list[~azure.storage.blob.models.ArrowField]
+ """
+
+ _validation = {
+ 'schema': {'required': True},
+ }
+
+ _attribute_map = {
+ 'schema': {'key': 'Schema', 'type': '[ArrowField]', 'xml': {'name': 'Schema', 'wrapped': True, 'itemsName': 'Field'}},
+ }
+ _xml_map = {
+ 'name': 'ArrowConfiguration'
+ }
+
+ def __init__(
+ self,
+ *,
+ schema: List["ArrowField"],
+ **kwargs
+ ):
+ super(ArrowConfiguration, self).__init__(**kwargs)
+ self.schema = schema
+
+
+class ArrowField(msrest.serialization.Model):
+ """Groups settings regarding specific field of an arrow schema.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param type: Required.
+ :type type: str
+ :param name:
+ :type name: str
+ :param precision:
+ :type precision: int
+ :param scale:
+ :type scale: int
+ """
+
+ _validation = {
+ 'type': {'required': True},
+ }
+
+ _attribute_map = {
+ 'type': {'key': 'Type', 'type': 'str'},
+ 'name': {'key': 'Name', 'type': 'str'},
+ 'precision': {'key': 'Precision', 'type': 'int'},
+ 'scale': {'key': 'Scale', 'type': 'int'},
+ }
+ _xml_map = {
+ 'name': 'Field'
+ }
+
+ def __init__(
+ self,
+ *,
+ type: str,
+ name: Optional[str] = None,
+ precision: Optional[int] = None,
+ scale: Optional[int] = None,
+ **kwargs
+ ):
+ super(ArrowField, self).__init__(**kwargs)
+ self.type = type
+ self.name = name
+ self.precision = precision
+ self.scale = scale
+
+
+class BlobFlatListSegment(msrest.serialization.Model):
+ """BlobFlatListSegment.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param blob_items: Required.
+ :type blob_items: list[~azure.storage.blob.models.BlobItemInternal]
+ """
+
+ _validation = {
+ 'blob_items': {'required': True},
+ }
+
+ _attribute_map = {
+ 'blob_items': {'key': 'BlobItems', 'type': '[BlobItemInternal]'},
+ }
+ _xml_map = {
+ 'name': 'Blobs'
+ }
+
+ def __init__(
+ self,
+ *,
+ blob_items: List["BlobItemInternal"],
+ **kwargs
+ ):
+ super(BlobFlatListSegment, self).__init__(**kwargs)
+ self.blob_items = blob_items
+
+
+class BlobHierarchyListSegment(msrest.serialization.Model):
+ """BlobHierarchyListSegment.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param blob_prefixes:
+ :type blob_prefixes: list[~azure.storage.blob.models.BlobPrefix]
+ :param blob_items: Required.
+ :type blob_items: list[~azure.storage.blob.models.BlobItemInternal]
+ """
+
+ _validation = {
+ 'blob_items': {'required': True},
+ }
+
+ _attribute_map = {
+ 'blob_prefixes': {'key': 'BlobPrefixes', 'type': '[BlobPrefix]', 'xml': {'name': 'BlobPrefix'}},
+ 'blob_items': {'key': 'BlobItems', 'type': '[BlobItemInternal]', 'xml': {'name': 'Blob', 'itemsName': 'Blob'}},
+ }
+ _xml_map = {
+ 'name': 'Blobs'
+ }
+
+ def __init__(
+ self,
+ *,
+ blob_items: List["BlobItemInternal"],
+ blob_prefixes: Optional[List["BlobPrefix"]] = None,
+ **kwargs
+ ):
+ super(BlobHierarchyListSegment, self).__init__(**kwargs)
+ self.blob_prefixes = blob_prefixes
+ self.blob_items = blob_items
+
+
+class BlobHTTPHeaders(msrest.serialization.Model):
+ """Parameter group.
+
+ :param blob_cache_control: Optional. Sets the blob's cache control. If specified, this property
+ is stored with the blob and returned with a read request.
+ :type blob_cache_control: str
+ :param blob_content_type: Optional. Sets the blob's content type. If specified, this property
+ is stored with the blob and returned with a read request.
+ :type blob_content_type: str
+ :param blob_content_md5: Optional. An MD5 hash of the blob content. Note that this hash is not
+ validated, as the hashes for the individual blocks were validated when each was uploaded.
+ :type blob_content_md5: bytearray
+ :param blob_content_encoding: Optional. Sets the blob's content encoding. If specified, this
+ property is stored with the blob and returned with a read request.
+ :type blob_content_encoding: str
+ :param blob_content_language: Optional. Set the blob's content language. If specified, this
+ property is stored with the blob and returned with a read request.
+ :type blob_content_language: str
+ :param blob_content_disposition: Optional. Sets the blob's Content-Disposition header.
+ :type blob_content_disposition: str
+ """
+
+ _attribute_map = {
+ 'blob_cache_control': {'key': 'blobCacheControl', 'type': 'str'},
+ 'blob_content_type': {'key': 'blobContentType', 'type': 'str'},
+ 'blob_content_md5': {'key': 'blobContentMD5', 'type': 'bytearray'},
+ 'blob_content_encoding': {'key': 'blobContentEncoding', 'type': 'str'},
+ 'blob_content_language': {'key': 'blobContentLanguage', 'type': 'str'},
+ 'blob_content_disposition': {'key': 'blobContentDisposition', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ blob_cache_control: Optional[str] = None,
+ blob_content_type: Optional[str] = None,
+ blob_content_md5: Optional[bytearray] = None,
+ blob_content_encoding: Optional[str] = None,
+ blob_content_language: Optional[str] = None,
+ blob_content_disposition: Optional[str] = None,
+ **kwargs
+ ):
+ super(BlobHTTPHeaders, self).__init__(**kwargs)
+ self.blob_cache_control = blob_cache_control
+ self.blob_content_type = blob_content_type
+ self.blob_content_md5 = blob_content_md5
+ self.blob_content_encoding = blob_content_encoding
+ self.blob_content_language = blob_content_language
+ self.blob_content_disposition = blob_content_disposition
+
+
+class BlobItemInternal(msrest.serialization.Model):
+ """An Azure Storage blob.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required.
+ :type name: ~azure.storage.blob.models.BlobName
+ :param deleted: Required.
+ :type deleted: bool
+ :param snapshot: Required.
+ :type snapshot: str
+ :param version_id:
+ :type version_id: str
+ :param is_current_version:
+ :type is_current_version: bool
+ :param properties: Required. Properties of a blob.
+ :type properties: ~azure.storage.blob.models.BlobPropertiesInternal
+ :param metadata:
+ :type metadata: ~azure.storage.blob.models.BlobMetadata
+ :param blob_tags: Blob tags.
+ :type blob_tags: ~azure.storage.blob.models.BlobTags
+ :param has_versions_only:
+ :type has_versions_only: bool
+ :param object_replication_metadata: Dictionary of :code:``.
+ :type object_replication_metadata: dict[str, str]
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ 'deleted': {'required': True},
+ 'snapshot': {'required': True},
+ 'properties': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'BlobName'},
+ 'deleted': {'key': 'Deleted', 'type': 'bool'},
+ 'snapshot': {'key': 'Snapshot', 'type': 'str'},
+ 'version_id': {'key': 'VersionId', 'type': 'str'},
+ 'is_current_version': {'key': 'IsCurrentVersion', 'type': 'bool'},
+ 'properties': {'key': 'Properties', 'type': 'BlobPropertiesInternal'},
+ 'metadata': {'key': 'Metadata', 'type': 'BlobMetadata'},
+ 'blob_tags': {'key': 'BlobTags', 'type': 'BlobTags'},
+ 'has_versions_only': {'key': 'HasVersionsOnly', 'type': 'bool'},
+ 'object_replication_metadata': {'key': 'OrMetadata', 'type': '{str}'},
+ }
+ _xml_map = {
+ 'name': 'Blob'
+ }
+
+ def __init__(
+ self,
+ *,
+ name: "BlobName",
+ deleted: bool,
+ snapshot: str,
+ properties: "BlobPropertiesInternal",
+ version_id: Optional[str] = None,
+ is_current_version: Optional[bool] = None,
+ metadata: Optional["BlobMetadata"] = None,
+ blob_tags: Optional["BlobTags"] = None,
+ has_versions_only: Optional[bool] = None,
+ object_replication_metadata: Optional[Dict[str, str]] = None,
+ **kwargs
+ ):
+ super(BlobItemInternal, self).__init__(**kwargs)
+ self.name = name
+ self.deleted = deleted
+ self.snapshot = snapshot
+ self.version_id = version_id
+ self.is_current_version = is_current_version
+ self.properties = properties
+ self.metadata = metadata
+ self.blob_tags = blob_tags
+ self.has_versions_only = has_versions_only
+ self.object_replication_metadata = object_replication_metadata
+
+
+class BlobMetadata(msrest.serialization.Model):
+ """BlobMetadata.
+
+ :param additional_properties: Unmatched properties from the message are deserialized to this
+ collection.
+ :type additional_properties: dict[str, str]
+ :param encrypted:
+ :type encrypted: str
+ """
+
+ _attribute_map = {
+ 'additional_properties': {'key': '', 'type': '{str}'},
+ 'encrypted': {'key': 'Encrypted', 'type': 'str', 'xml': {'attr': True}},
+ }
+ _xml_map = {
+ 'name': 'Metadata'
+ }
+
+ def __init__(
+ self,
+ *,
+ additional_properties: Optional[Dict[str, str]] = None,
+ encrypted: Optional[str] = None,
+ **kwargs
+ ):
+ super(BlobMetadata, self).__init__(**kwargs)
+ self.additional_properties = additional_properties
+ self.encrypted = encrypted
+
+
+class BlobName(msrest.serialization.Model):
+ """BlobName.
+
+ :param encoded: Indicates if the blob name is encoded.
+ :type encoded: bool
+ :param content: The name of the blob.
+ :type content: str
+ """
+
+ _attribute_map = {
+ 'encoded': {'key': 'Encoded', 'type': 'bool', 'xml': {'name': 'Encoded', 'attr': True}},
+ 'content': {'key': 'content', 'type': 'str', 'xml': {'text': True}},
+ }
+
+ def __init__(
+ self,
+ *,
+ encoded: Optional[bool] = None,
+ content: Optional[str] = None,
+ **kwargs
+ ):
+ super(BlobName, self).__init__(**kwargs)
+ self.encoded = encoded
+ self.content = content
+
+
+class BlobPrefix(msrest.serialization.Model):
+ """BlobPrefix.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required.
+ :type name: ~azure.storage.blob.models.BlobName
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'BlobName'},
+ }
+
+ def __init__(
+ self,
+ *,
+ name: "BlobName",
+ **kwargs
+ ):
+ super(BlobPrefix, self).__init__(**kwargs)
+ self.name = name
+
+
+class BlobPropertiesInternal(msrest.serialization.Model):
+ """Properties of a blob.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param creation_time:
+ :type creation_time: ~datetime.datetime
+ :param last_modified: Required.
+ :type last_modified: ~datetime.datetime
+ :param etag: Required.
+ :type etag: str
+ :param content_length: Size in bytes.
+ :type content_length: long
+ :param content_type:
+ :type content_type: str
+ :param content_encoding:
+ :type content_encoding: str
+ :param content_language:
+ :type content_language: str
+ :param content_md5:
+ :type content_md5: bytearray
+ :param content_disposition:
+ :type content_disposition: str
+ :param cache_control:
+ :type cache_control: str
+ :param blob_sequence_number:
+ :type blob_sequence_number: long
+ :param blob_type: Possible values include: "BlockBlob", "PageBlob", "AppendBlob".
+ :type blob_type: str or ~azure.storage.blob.models.BlobType
+ :param lease_status: Possible values include: "locked", "unlocked".
+ :type lease_status: str or ~azure.storage.blob.models.LeaseStatusType
+ :param lease_state: Possible values include: "available", "leased", "expired", "breaking",
+ "broken".
+ :type lease_state: str or ~azure.storage.blob.models.LeaseStateType
+ :param lease_duration: Possible values include: "infinite", "fixed".
+ :type lease_duration: str or ~azure.storage.blob.models.LeaseDurationType
+ :param copy_id:
+ :type copy_id: str
+ :param copy_status: Possible values include: "pending", "success", "aborted", "failed".
+ :type copy_status: str or ~azure.storage.blob.models.CopyStatusType
+ :param copy_source:
+ :type copy_source: str
+ :param copy_progress:
+ :type copy_progress: str
+ :param copy_completion_time:
+ :type copy_completion_time: ~datetime.datetime
+ :param copy_status_description:
+ :type copy_status_description: str
+ :param server_encrypted:
+ :type server_encrypted: bool
+ :param incremental_copy:
+ :type incremental_copy: bool
+ :param destination_snapshot:
+ :type destination_snapshot: str
+ :param deleted_time:
+ :type deleted_time: ~datetime.datetime
+ :param remaining_retention_days:
+ :type remaining_retention_days: int
+ :param access_tier: Possible values include: "P4", "P6", "P10", "P15", "P20", "P30", "P40",
+ "P50", "P60", "P70", "P80", "Hot", "Cool", "Archive".
+ :type access_tier: str or ~azure.storage.blob.models.AccessTier
+ :param access_tier_inferred:
+ :type access_tier_inferred: bool
+ :param archive_status: Possible values include: "rehydrate-pending-to-hot",
+ "rehydrate-pending-to-cool".
+ :type archive_status: str or ~azure.storage.blob.models.ArchiveStatus
+ :param customer_provided_key_sha256:
+ :type customer_provided_key_sha256: str
+ :param encryption_scope: The name of the encryption scope under which the blob is encrypted.
+ :type encryption_scope: str
+ :param access_tier_change_time:
+ :type access_tier_change_time: ~datetime.datetime
+ :param tag_count:
+ :type tag_count: int
+ :param expires_on:
+ :type expires_on: ~datetime.datetime
+ :param is_sealed:
+ :type is_sealed: bool
+ :param rehydrate_priority: If an object is in rehydrate pending state then this header is
+ returned with priority of rehydrate. Valid values are High and Standard. Possible values
+ include: "High", "Standard".
+ :type rehydrate_priority: str or ~azure.storage.blob.models.RehydratePriority
+ :param last_accessed_on:
+ :type last_accessed_on: ~datetime.datetime
+ :param immutability_policy_expires_on:
+ :type immutability_policy_expires_on: ~datetime.datetime
+ :param immutability_policy_mode: Possible values include: "Mutable", "Unlocked", "Locked".
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold:
+ :type legal_hold: bool
+ """
+
+ _validation = {
+ 'last_modified': {'required': True},
+ 'etag': {'required': True},
+ }
+
+ _attribute_map = {
+ 'creation_time': {'key': 'Creation-Time', 'type': 'rfc-1123'},
+ 'last_modified': {'key': 'Last-Modified', 'type': 'rfc-1123'},
+ 'etag': {'key': 'Etag', 'type': 'str'},
+ 'content_length': {'key': 'Content-Length', 'type': 'long'},
+ 'content_type': {'key': 'Content-Type', 'type': 'str'},
+ 'content_encoding': {'key': 'Content-Encoding', 'type': 'str'},
+ 'content_language': {'key': 'Content-Language', 'type': 'str'},
+ 'content_md5': {'key': 'Content-MD5', 'type': 'bytearray'},
+ 'content_disposition': {'key': 'Content-Disposition', 'type': 'str'},
+ 'cache_control': {'key': 'Cache-Control', 'type': 'str'},
+ 'blob_sequence_number': {'key': 'x-ms-blob-sequence-number', 'type': 'long'},
+ 'blob_type': {'key': 'BlobType', 'type': 'str'},
+ 'lease_status': {'key': 'LeaseStatus', 'type': 'str'},
+ 'lease_state': {'key': 'LeaseState', 'type': 'str'},
+ 'lease_duration': {'key': 'LeaseDuration', 'type': 'str'},
+ 'copy_id': {'key': 'CopyId', 'type': 'str'},
+ 'copy_status': {'key': 'CopyStatus', 'type': 'str'},
+ 'copy_source': {'key': 'CopySource', 'type': 'str'},
+ 'copy_progress': {'key': 'CopyProgress', 'type': 'str'},
+ 'copy_completion_time': {'key': 'CopyCompletionTime', 'type': 'rfc-1123'},
+ 'copy_status_description': {'key': 'CopyStatusDescription', 'type': 'str'},
+ 'server_encrypted': {'key': 'ServerEncrypted', 'type': 'bool'},
+ 'incremental_copy': {'key': 'IncrementalCopy', 'type': 'bool'},
+ 'destination_snapshot': {'key': 'DestinationSnapshot', 'type': 'str'},
+ 'deleted_time': {'key': 'DeletedTime', 'type': 'rfc-1123'},
+ 'remaining_retention_days': {'key': 'RemainingRetentionDays', 'type': 'int'},
+ 'access_tier': {'key': 'AccessTier', 'type': 'str'},
+ 'access_tier_inferred': {'key': 'AccessTierInferred', 'type': 'bool'},
+ 'archive_status': {'key': 'ArchiveStatus', 'type': 'str'},
+ 'customer_provided_key_sha256': {'key': 'CustomerProvidedKeySha256', 'type': 'str'},
+ 'encryption_scope': {'key': 'EncryptionScope', 'type': 'str'},
+ 'access_tier_change_time': {'key': 'AccessTierChangeTime', 'type': 'rfc-1123'},
+ 'tag_count': {'key': 'TagCount', 'type': 'int'},
+ 'expires_on': {'key': 'Expiry-Time', 'type': 'rfc-1123'},
+ 'is_sealed': {'key': 'Sealed', 'type': 'bool'},
+ 'rehydrate_priority': {'key': 'RehydratePriority', 'type': 'str'},
+ 'last_accessed_on': {'key': 'LastAccessTime', 'type': 'rfc-1123'},
+ 'immutability_policy_expires_on': {'key': 'ImmutabilityPolicyUntilDate', 'type': 'rfc-1123'},
+ 'immutability_policy_mode': {'key': 'ImmutabilityPolicyMode', 'type': 'str'},
+ 'legal_hold': {'key': 'LegalHold', 'type': 'bool'},
+ }
+ _xml_map = {
+ 'name': 'Properties'
+ }
+
+ def __init__(
+ self,
+ *,
+ last_modified: datetime.datetime,
+ etag: str,
+ creation_time: Optional[datetime.datetime] = None,
+ content_length: Optional[int] = None,
+ content_type: Optional[str] = None,
+ content_encoding: Optional[str] = None,
+ content_language: Optional[str] = None,
+ content_md5: Optional[bytearray] = None,
+ content_disposition: Optional[str] = None,
+ cache_control: Optional[str] = None,
+ blob_sequence_number: Optional[int] = None,
+ blob_type: Optional[Union[str, "BlobType"]] = None,
+ lease_status: Optional[Union[str, "LeaseStatusType"]] = None,
+ lease_state: Optional[Union[str, "LeaseStateType"]] = None,
+ lease_duration: Optional[Union[str, "LeaseDurationType"]] = None,
+ copy_id: Optional[str] = None,
+ copy_status: Optional[Union[str, "CopyStatusType"]] = None,
+ copy_source: Optional[str] = None,
+ copy_progress: Optional[str] = None,
+ copy_completion_time: Optional[datetime.datetime] = None,
+ copy_status_description: Optional[str] = None,
+ server_encrypted: Optional[bool] = None,
+ incremental_copy: Optional[bool] = None,
+ destination_snapshot: Optional[str] = None,
+ deleted_time: Optional[datetime.datetime] = None,
+ remaining_retention_days: Optional[int] = None,
+ access_tier: Optional[Union[str, "AccessTier"]] = None,
+ access_tier_inferred: Optional[bool] = None,
+ archive_status: Optional[Union[str, "ArchiveStatus"]] = None,
+ customer_provided_key_sha256: Optional[str] = None,
+ encryption_scope: Optional[str] = None,
+ access_tier_change_time: Optional[datetime.datetime] = None,
+ tag_count: Optional[int] = None,
+ expires_on: Optional[datetime.datetime] = None,
+ is_sealed: Optional[bool] = None,
+ rehydrate_priority: Optional[Union[str, "RehydratePriority"]] = None,
+ last_accessed_on: Optional[datetime.datetime] = None,
+ immutability_policy_expires_on: Optional[datetime.datetime] = None,
+ immutability_policy_mode: Optional[Union[str, "BlobImmutabilityPolicyMode"]] = None,
+ legal_hold: Optional[bool] = None,
+ **kwargs
+ ):
+ super(BlobPropertiesInternal, self).__init__(**kwargs)
+ self.creation_time = creation_time
+ self.last_modified = last_modified
+ self.etag = etag
+ self.content_length = content_length
+ self.content_type = content_type
+ self.content_encoding = content_encoding
+ self.content_language = content_language
+ self.content_md5 = content_md5
+ self.content_disposition = content_disposition
+ self.cache_control = cache_control
+ self.blob_sequence_number = blob_sequence_number
+ self.blob_type = blob_type
+ self.lease_status = lease_status
+ self.lease_state = lease_state
+ self.lease_duration = lease_duration
+ self.copy_id = copy_id
+ self.copy_status = copy_status
+ self.copy_source = copy_source
+ self.copy_progress = copy_progress
+ self.copy_completion_time = copy_completion_time
+ self.copy_status_description = copy_status_description
+ self.server_encrypted = server_encrypted
+ self.incremental_copy = incremental_copy
+ self.destination_snapshot = destination_snapshot
+ self.deleted_time = deleted_time
+ self.remaining_retention_days = remaining_retention_days
+ self.access_tier = access_tier
+ self.access_tier_inferred = access_tier_inferred
+ self.archive_status = archive_status
+ self.customer_provided_key_sha256 = customer_provided_key_sha256
+ self.encryption_scope = encryption_scope
+ self.access_tier_change_time = access_tier_change_time
+ self.tag_count = tag_count
+ self.expires_on = expires_on
+ self.is_sealed = is_sealed
+ self.rehydrate_priority = rehydrate_priority
+ self.last_accessed_on = last_accessed_on
+ self.immutability_policy_expires_on = immutability_policy_expires_on
+ self.immutability_policy_mode = immutability_policy_mode
+ self.legal_hold = legal_hold
+
+
+class BlobTag(msrest.serialization.Model):
+ """BlobTag.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param key: Required.
+ :type key: str
+ :param value: Required.
+ :type value: str
+ """
+
+ _validation = {
+ 'key': {'required': True},
+ 'value': {'required': True},
+ }
+
+ _attribute_map = {
+ 'key': {'key': 'Key', 'type': 'str'},
+ 'value': {'key': 'Value', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'Tag'
+ }
+
+ def __init__(
+ self,
+ *,
+ key: str,
+ value: str,
+ **kwargs
+ ):
+ super(BlobTag, self).__init__(**kwargs)
+ self.key = key
+ self.value = value
+
+
+class BlobTags(msrest.serialization.Model):
+ """Blob tags.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param blob_tag_set: Required.
+ :type blob_tag_set: list[~azure.storage.blob.models.BlobTag]
+ """
+
+ _validation = {
+ 'blob_tag_set': {'required': True},
+ }
+
+ _attribute_map = {
+ 'blob_tag_set': {'key': 'BlobTagSet', 'type': '[BlobTag]', 'xml': {'name': 'TagSet', 'wrapped': True, 'itemsName': 'Tag'}},
+ }
+ _xml_map = {
+ 'name': 'Tags'
+ }
+
+ def __init__(
+ self,
+ *,
+ blob_tag_set: List["BlobTag"],
+ **kwargs
+ ):
+ super(BlobTags, self).__init__(**kwargs)
+ self.blob_tag_set = blob_tag_set
+
+
+class Block(msrest.serialization.Model):
+ """Represents a single block in a block blob. It describes the block's ID and size.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required. The base64 encoded block ID.
+ :type name: str
+ :param size: Required. The block size in bytes.
+ :type size: long
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ 'size': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'str'},
+ 'size': {'key': 'Size', 'type': 'long'},
+ }
+
+ def __init__(
+ self,
+ *,
+ name: str,
+ size: int,
+ **kwargs
+ ):
+ super(Block, self).__init__(**kwargs)
+ self.name = name
+ self.size = size
+
+
+class BlockList(msrest.serialization.Model):
+ """BlockList.
+
+ :param committed_blocks:
+ :type committed_blocks: list[~azure.storage.blob.models.Block]
+ :param uncommitted_blocks:
+ :type uncommitted_blocks: list[~azure.storage.blob.models.Block]
+ """
+
+ _attribute_map = {
+ 'committed_blocks': {'key': 'CommittedBlocks', 'type': '[Block]', 'xml': {'wrapped': True}},
+ 'uncommitted_blocks': {'key': 'UncommittedBlocks', 'type': '[Block]', 'xml': {'wrapped': True}},
+ }
+
+ def __init__(
+ self,
+ *,
+ committed_blocks: Optional[List["Block"]] = None,
+ uncommitted_blocks: Optional[List["Block"]] = None,
+ **kwargs
+ ):
+ super(BlockList, self).__init__(**kwargs)
+ self.committed_blocks = committed_blocks
+ self.uncommitted_blocks = uncommitted_blocks
+
+
+class BlockLookupList(msrest.serialization.Model):
+ """BlockLookupList.
+
+ :param committed:
+ :type committed: list[str]
+ :param uncommitted:
+ :type uncommitted: list[str]
+ :param latest:
+ :type latest: list[str]
+ """
+
+ _attribute_map = {
+ 'committed': {'key': 'Committed', 'type': '[str]', 'xml': {'itemsName': 'Committed'}},
+ 'uncommitted': {'key': 'Uncommitted', 'type': '[str]', 'xml': {'itemsName': 'Uncommitted'}},
+ 'latest': {'key': 'Latest', 'type': '[str]', 'xml': {'itemsName': 'Latest'}},
+ }
+ _xml_map = {
+ 'name': 'BlockList'
+ }
+
+ def __init__(
+ self,
+ *,
+ committed: Optional[List[str]] = None,
+ uncommitted: Optional[List[str]] = None,
+ latest: Optional[List[str]] = None,
+ **kwargs
+ ):
+ super(BlockLookupList, self).__init__(**kwargs)
+ self.committed = committed
+ self.uncommitted = uncommitted
+ self.latest = latest
+
+
+class ClearRange(msrest.serialization.Model):
+ """ClearRange.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param start: Required.
+ :type start: long
+ :param end: Required.
+ :type end: long
+ """
+
+ _validation = {
+ 'start': {'required': True},
+ 'end': {'required': True},
+ }
+
+ _attribute_map = {
+ 'start': {'key': 'Start', 'type': 'long', 'xml': {'name': 'Start'}},
+ 'end': {'key': 'End', 'type': 'long', 'xml': {'name': 'End'}},
+ }
+ _xml_map = {
+ 'name': 'ClearRange'
+ }
+
+ def __init__(
+ self,
+ *,
+ start: int,
+ end: int,
+ **kwargs
+ ):
+ super(ClearRange, self).__init__(**kwargs)
+ self.start = start
+ self.end = end
+
+
+class ContainerCpkScopeInfo(msrest.serialization.Model):
+ """Parameter group.
+
+ :param default_encryption_scope: Optional. Version 2019-07-07 and later. Specifies the
+ default encryption scope to set on the container and use for all future writes.
+ :type default_encryption_scope: str
+ :param prevent_encryption_scope_override: Optional. Version 2019-07-07 and newer. If true,
+ prevents any request from specifying a different encryption scope than the scope set on the
+ container.
+ :type prevent_encryption_scope_override: bool
+ """
+
+ _attribute_map = {
+ 'default_encryption_scope': {'key': 'DefaultEncryptionScope', 'type': 'str'},
+ 'prevent_encryption_scope_override': {'key': 'PreventEncryptionScopeOverride', 'type': 'bool'},
+ }
+
+ def __init__(
+ self,
+ *,
+ default_encryption_scope: Optional[str] = None,
+ prevent_encryption_scope_override: Optional[bool] = None,
+ **kwargs
+ ):
+ super(ContainerCpkScopeInfo, self).__init__(**kwargs)
+ self.default_encryption_scope = default_encryption_scope
+ self.prevent_encryption_scope_override = prevent_encryption_scope_override
+
+
+class ContainerItem(msrest.serialization.Model):
+ """An Azure Storage container.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required.
+ :type name: str
+ :param deleted:
+ :type deleted: bool
+ :param version:
+ :type version: str
+ :param properties: Required. Properties of a container.
+ :type properties: ~azure.storage.blob.models.ContainerProperties
+ :param metadata: Dictionary of :code:``.
+ :type metadata: dict[str, str]
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ 'properties': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'str'},
+ 'deleted': {'key': 'Deleted', 'type': 'bool'},
+ 'version': {'key': 'Version', 'type': 'str'},
+ 'properties': {'key': 'Properties', 'type': 'ContainerProperties'},
+ 'metadata': {'key': 'Metadata', 'type': '{str}'},
+ }
+ _xml_map = {
+ 'name': 'Container'
+ }
+
+ def __init__(
+ self,
+ *,
+ name: str,
+ properties: "ContainerProperties",
+ deleted: Optional[bool] = None,
+ version: Optional[str] = None,
+ metadata: Optional[Dict[str, str]] = None,
+ **kwargs
+ ):
+ super(ContainerItem, self).__init__(**kwargs)
+ self.name = name
+ self.deleted = deleted
+ self.version = version
+ self.properties = properties
+ self.metadata = metadata
+
+
+class ContainerProperties(msrest.serialization.Model):
+ """Properties of a container.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param last_modified: Required.
+ :type last_modified: ~datetime.datetime
+ :param etag: Required.
+ :type etag: str
+ :param lease_status: Possible values include: "locked", "unlocked".
+ :type lease_status: str or ~azure.storage.blob.models.LeaseStatusType
+ :param lease_state: Possible values include: "available", "leased", "expired", "breaking",
+ "broken".
+ :type lease_state: str or ~azure.storage.blob.models.LeaseStateType
+ :param lease_duration: Possible values include: "infinite", "fixed".
+ :type lease_duration: str or ~azure.storage.blob.models.LeaseDurationType
+ :param public_access: Possible values include: "container", "blob".
+ :type public_access: str or ~azure.storage.blob.models.PublicAccessType
+ :param has_immutability_policy:
+ :type has_immutability_policy: bool
+ :param has_legal_hold:
+ :type has_legal_hold: bool
+ :param default_encryption_scope:
+ :type default_encryption_scope: str
+ :param prevent_encryption_scope_override:
+ :type prevent_encryption_scope_override: bool
+ :param deleted_time:
+ :type deleted_time: ~datetime.datetime
+ :param remaining_retention_days:
+ :type remaining_retention_days: int
+ :param is_immutable_storage_with_versioning_enabled: Indicates if version level worm is enabled
+ on this container.
+ :type is_immutable_storage_with_versioning_enabled: bool
+ """
+
+ _validation = {
+ 'last_modified': {'required': True},
+ 'etag': {'required': True},
+ }
+
+ _attribute_map = {
+ 'last_modified': {'key': 'Last-Modified', 'type': 'rfc-1123'},
+ 'etag': {'key': 'Etag', 'type': 'str'},
+ 'lease_status': {'key': 'LeaseStatus', 'type': 'str'},
+ 'lease_state': {'key': 'LeaseState', 'type': 'str'},
+ 'lease_duration': {'key': 'LeaseDuration', 'type': 'str'},
+ 'public_access': {'key': 'PublicAccess', 'type': 'str'},
+ 'has_immutability_policy': {'key': 'HasImmutabilityPolicy', 'type': 'bool'},
+ 'has_legal_hold': {'key': 'HasLegalHold', 'type': 'bool'},
+ 'default_encryption_scope': {'key': 'DefaultEncryptionScope', 'type': 'str'},
+ 'prevent_encryption_scope_override': {'key': 'DenyEncryptionScopeOverride', 'type': 'bool'},
+ 'deleted_time': {'key': 'DeletedTime', 'type': 'rfc-1123'},
+ 'remaining_retention_days': {'key': 'RemainingRetentionDays', 'type': 'int'},
+ 'is_immutable_storage_with_versioning_enabled': {'key': 'ImmutableStorageWithVersioningEnabled', 'type': 'bool'},
+ }
+
+ def __init__(
+ self,
+ *,
+ last_modified: datetime.datetime,
+ etag: str,
+ lease_status: Optional[Union[str, "LeaseStatusType"]] = None,
+ lease_state: Optional[Union[str, "LeaseStateType"]] = None,
+ lease_duration: Optional[Union[str, "LeaseDurationType"]] = None,
+ public_access: Optional[Union[str, "PublicAccessType"]] = None,
+ has_immutability_policy: Optional[bool] = None,
+ has_legal_hold: Optional[bool] = None,
+ default_encryption_scope: Optional[str] = None,
+ prevent_encryption_scope_override: Optional[bool] = None,
+ deleted_time: Optional[datetime.datetime] = None,
+ remaining_retention_days: Optional[int] = None,
+ is_immutable_storage_with_versioning_enabled: Optional[bool] = None,
+ **kwargs
+ ):
+ super(ContainerProperties, self).__init__(**kwargs)
+ self.last_modified = last_modified
+ self.etag = etag
+ self.lease_status = lease_status
+ self.lease_state = lease_state
+ self.lease_duration = lease_duration
+ self.public_access = public_access
+ self.has_immutability_policy = has_immutability_policy
+ self.has_legal_hold = has_legal_hold
+ self.default_encryption_scope = default_encryption_scope
+ self.prevent_encryption_scope_override = prevent_encryption_scope_override
+ self.deleted_time = deleted_time
+ self.remaining_retention_days = remaining_retention_days
+ self.is_immutable_storage_with_versioning_enabled = is_immutable_storage_with_versioning_enabled
+
+
+class CorsRule(msrest.serialization.Model):
+ """CORS is an HTTP feature that enables a web application running under one domain to access resources in another domain. Web browsers implement a security restriction known as same-origin policy that prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain (the origin domain) to call APIs in another domain.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param allowed_origins: Required. The origin domains that are permitted to make a request
+ against the storage service via CORS. The origin domain is the domain from which the request
+ originates. Note that the origin must be an exact case-sensitive match with the origin that the
+ user age sends to the service. You can also use the wildcard character '*' to allow all origin
+ domains to make requests via CORS.
+ :type allowed_origins: str
+ :param allowed_methods: Required. The methods (HTTP request verbs) that the origin domain may
+ use for a CORS request. (comma separated).
+ :type allowed_methods: str
+ :param allowed_headers: Required. the request headers that the origin domain may specify on the
+ CORS request.
+ :type allowed_headers: str
+ :param exposed_headers: Required. The response headers that may be sent in the response to the
+ CORS request and exposed by the browser to the request issuer.
+ :type exposed_headers: str
+ :param max_age_in_seconds: Required. The maximum amount time that a browser should cache the
+ preflight OPTIONS request.
+ :type max_age_in_seconds: int
+ """
+
+ _validation = {
+ 'allowed_origins': {'required': True},
+ 'allowed_methods': {'required': True},
+ 'allowed_headers': {'required': True},
+ 'exposed_headers': {'required': True},
+ 'max_age_in_seconds': {'required': True, 'minimum': 0},
+ }
+
+ _attribute_map = {
+ 'allowed_origins': {'key': 'AllowedOrigins', 'type': 'str'},
+ 'allowed_methods': {'key': 'AllowedMethods', 'type': 'str'},
+ 'allowed_headers': {'key': 'AllowedHeaders', 'type': 'str'},
+ 'exposed_headers': {'key': 'ExposedHeaders', 'type': 'str'},
+ 'max_age_in_seconds': {'key': 'MaxAgeInSeconds', 'type': 'int'},
+ }
+
+ def __init__(
+ self,
+ *,
+ allowed_origins: str,
+ allowed_methods: str,
+ allowed_headers: str,
+ exposed_headers: str,
+ max_age_in_seconds: int,
+ **kwargs
+ ):
+ super(CorsRule, self).__init__(**kwargs)
+ self.allowed_origins = allowed_origins
+ self.allowed_methods = allowed_methods
+ self.allowed_headers = allowed_headers
+ self.exposed_headers = exposed_headers
+ self.max_age_in_seconds = max_age_in_seconds
+
+
+class CpkInfo(msrest.serialization.Model):
+ """Parameter group.
+
+ :param encryption_key: Optional. Specifies the encryption key to use to encrypt the data
+ provided in the request. If not specified, encryption is performed with the root account
+ encryption key. For more information, see Encryption at Rest for Azure Storage Services.
+ :type encryption_key: str
+ :param encryption_key_sha256: The SHA-256 hash of the provided encryption key. Must be provided
+ if the x-ms-encryption-key header is provided.
+ :type encryption_key_sha256: str
+ :param encryption_algorithm: The algorithm used to produce the encryption key hash. Currently,
+ the only accepted value is "AES256". Must be provided if the x-ms-encryption-key header is
+ provided. Possible values include: "None", "AES256".
+ :type encryption_algorithm: str or ~azure.storage.blob.models.EncryptionAlgorithmType
+ """
+
+ _attribute_map = {
+ 'encryption_key': {'key': 'encryptionKey', 'type': 'str'},
+ 'encryption_key_sha256': {'key': 'encryptionKeySha256', 'type': 'str'},
+ 'encryption_algorithm': {'key': 'encryptionAlgorithm', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ encryption_key: Optional[str] = None,
+ encryption_key_sha256: Optional[str] = None,
+ encryption_algorithm: Optional[Union[str, "EncryptionAlgorithmType"]] = None,
+ **kwargs
+ ):
+ super(CpkInfo, self).__init__(**kwargs)
+ self.encryption_key = encryption_key
+ self.encryption_key_sha256 = encryption_key_sha256
+ self.encryption_algorithm = encryption_algorithm
+
+
+class CpkScopeInfo(msrest.serialization.Model):
+ """Parameter group.
+
+ :param encryption_scope: Optional. Version 2019-07-07 and later. Specifies the name of the
+ encryption scope to use to encrypt the data provided in the request. If not specified,
+ encryption is performed with the default account encryption scope. For more information, see
+ Encryption at Rest for Azure Storage Services.
+ :type encryption_scope: str
+ """
+
+ _attribute_map = {
+ 'encryption_scope': {'key': 'encryptionScope', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ encryption_scope: Optional[str] = None,
+ **kwargs
+ ):
+ super(CpkScopeInfo, self).__init__(**kwargs)
+ self.encryption_scope = encryption_scope
+
+
+class DelimitedTextConfiguration(msrest.serialization.Model):
+ """Groups the settings used for interpreting the blob data if the blob is delimited text formatted.
+
+ :param column_separator: The string used to separate columns.
+ :type column_separator: str
+ :param field_quote: The string used to quote a specific field.
+ :type field_quote: str
+ :param record_separator: The string used to separate records.
+ :type record_separator: str
+ :param escape_char: The string used as an escape character.
+ :type escape_char: str
+ :param headers_present: Represents whether the data has headers.
+ :type headers_present: bool
+ """
+
+ _attribute_map = {
+ 'column_separator': {'key': 'ColumnSeparator', 'type': 'str', 'xml': {'name': 'ColumnSeparator'}},
+ 'field_quote': {'key': 'FieldQuote', 'type': 'str', 'xml': {'name': 'FieldQuote'}},
+ 'record_separator': {'key': 'RecordSeparator', 'type': 'str', 'xml': {'name': 'RecordSeparator'}},
+ 'escape_char': {'key': 'EscapeChar', 'type': 'str', 'xml': {'name': 'EscapeChar'}},
+ 'headers_present': {'key': 'HeadersPresent', 'type': 'bool', 'xml': {'name': 'HasHeaders'}},
+ }
+ _xml_map = {
+ 'name': 'DelimitedTextConfiguration'
+ }
+
+ def __init__(
+ self,
+ *,
+ column_separator: Optional[str] = None,
+ field_quote: Optional[str] = None,
+ record_separator: Optional[str] = None,
+ escape_char: Optional[str] = None,
+ headers_present: Optional[bool] = None,
+ **kwargs
+ ):
+ super(DelimitedTextConfiguration, self).__init__(**kwargs)
+ self.column_separator = column_separator
+ self.field_quote = field_quote
+ self.record_separator = record_separator
+ self.escape_char = escape_char
+ self.headers_present = headers_present
+
+
+class FilterBlobItem(msrest.serialization.Model):
+ """Blob info from a Filter Blobs API call.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param name: Required.
+ :type name: str
+ :param container_name: Required.
+ :type container_name: str
+ :param tags: A set of tags. Blob tags.
+ :type tags: ~azure.storage.blob.models.BlobTags
+ """
+
+ _validation = {
+ 'name': {'required': True},
+ 'container_name': {'required': True},
+ }
+
+ _attribute_map = {
+ 'name': {'key': 'Name', 'type': 'str'},
+ 'container_name': {'key': 'ContainerName', 'type': 'str'},
+ 'tags': {'key': 'Tags', 'type': 'BlobTags'},
+ }
+ _xml_map = {
+ 'name': 'Blob'
+ }
+
+ def __init__(
+ self,
+ *,
+ name: str,
+ container_name: str,
+ tags: Optional["BlobTags"] = None,
+ **kwargs
+ ):
+ super(FilterBlobItem, self).__init__(**kwargs)
+ self.name = name
+ self.container_name = container_name
+ self.tags = tags
+
+
+class FilterBlobSegment(msrest.serialization.Model):
+ """The result of a Filter Blobs API call.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param service_endpoint: Required.
+ :type service_endpoint: str
+ :param where: Required.
+ :type where: str
+ :param blobs: Required.
+ :type blobs: list[~azure.storage.blob.models.FilterBlobItem]
+ :param next_marker:
+ :type next_marker: str
+ """
+
+ _validation = {
+ 'service_endpoint': {'required': True},
+ 'where': {'required': True},
+ 'blobs': {'required': True},
+ }
+
+ _attribute_map = {
+ 'service_endpoint': {'key': 'ServiceEndpoint', 'type': 'str', 'xml': {'attr': True}},
+ 'where': {'key': 'Where', 'type': 'str'},
+ 'blobs': {'key': 'Blobs', 'type': '[FilterBlobItem]', 'xml': {'name': 'Blobs', 'wrapped': True, 'itemsName': 'Blob'}},
+ 'next_marker': {'key': 'NextMarker', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'EnumerationResults'
+ }
+
+ def __init__(
+ self,
+ *,
+ service_endpoint: str,
+ where: str,
+ blobs: List["FilterBlobItem"],
+ next_marker: Optional[str] = None,
+ **kwargs
+ ):
+ super(FilterBlobSegment, self).__init__(**kwargs)
+ self.service_endpoint = service_endpoint
+ self.where = where
+ self.blobs = blobs
+ self.next_marker = next_marker
+
+
+class GeoReplication(msrest.serialization.Model):
+ """Geo-Replication information for the Secondary Storage Service.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param status: Required. The status of the secondary location. Possible values include: "live",
+ "bootstrap", "unavailable".
+ :type status: str or ~azure.storage.blob.models.GeoReplicationStatusType
+ :param last_sync_time: Required. A GMT date/time value, to the second. All primary writes
+ preceding this value are guaranteed to be available for read operations at the secondary.
+ Primary writes after this point in time may or may not be available for reads.
+ :type last_sync_time: ~datetime.datetime
+ """
+
+ _validation = {
+ 'status': {'required': True},
+ 'last_sync_time': {'required': True},
+ }
+
+ _attribute_map = {
+ 'status': {'key': 'Status', 'type': 'str'},
+ 'last_sync_time': {'key': 'LastSyncTime', 'type': 'rfc-1123'},
+ }
+
+ def __init__(
+ self,
+ *,
+ status: Union[str, "GeoReplicationStatusType"],
+ last_sync_time: datetime.datetime,
+ **kwargs
+ ):
+ super(GeoReplication, self).__init__(**kwargs)
+ self.status = status
+ self.last_sync_time = last_sync_time
+
+
+class JsonTextConfiguration(msrest.serialization.Model):
+ """json text configuration.
+
+ :param record_separator: The string used to separate records.
+ :type record_separator: str
+ """
+
+ _attribute_map = {
+ 'record_separator': {'key': 'RecordSeparator', 'type': 'str', 'xml': {'name': 'RecordSeparator'}},
+ }
+ _xml_map = {
+ 'name': 'JsonTextConfiguration'
+ }
+
+ def __init__(
+ self,
+ *,
+ record_separator: Optional[str] = None,
+ **kwargs
+ ):
+ super(JsonTextConfiguration, self).__init__(**kwargs)
+ self.record_separator = record_separator
+
+
+class KeyInfo(msrest.serialization.Model):
+ """Key information.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param start: Required. The date-time the key is active in ISO 8601 UTC time.
+ :type start: str
+ :param expiry: Required. The date-time the key expires in ISO 8601 UTC time.
+ :type expiry: str
+ """
+
+ _validation = {
+ 'start': {'required': True},
+ 'expiry': {'required': True},
+ }
+
+ _attribute_map = {
+ 'start': {'key': 'Start', 'type': 'str'},
+ 'expiry': {'key': 'Expiry', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ start: str,
+ expiry: str,
+ **kwargs
+ ):
+ super(KeyInfo, self).__init__(**kwargs)
+ self.start = start
+ self.expiry = expiry
+
+
+class LeaseAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param lease_id: If specified, the operation only succeeds if the resource's lease is active
+ and matches this ID.
+ :type lease_id: str
+ """
+
+ _attribute_map = {
+ 'lease_id': {'key': 'leaseId', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ lease_id: Optional[str] = None,
+ **kwargs
+ ):
+ super(LeaseAccessConditions, self).__init__(**kwargs)
+ self.lease_id = lease_id
+
+
+class ListBlobsFlatSegmentResponse(msrest.serialization.Model):
+ """An enumeration of blobs.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param service_endpoint: Required.
+ :type service_endpoint: str
+ :param container_name: Required.
+ :type container_name: str
+ :param prefix:
+ :type prefix: str
+ :param marker:
+ :type marker: str
+ :param max_results:
+ :type max_results: int
+ :param segment: Required.
+ :type segment: ~azure.storage.blob.models.BlobFlatListSegment
+ :param next_marker:
+ :type next_marker: str
+ """
+
+ _validation = {
+ 'service_endpoint': {'required': True},
+ 'container_name': {'required': True},
+ 'segment': {'required': True},
+ }
+
+ _attribute_map = {
+ 'service_endpoint': {'key': 'ServiceEndpoint', 'type': 'str', 'xml': {'attr': True}},
+ 'container_name': {'key': 'ContainerName', 'type': 'str', 'xml': {'attr': True}},
+ 'prefix': {'key': 'Prefix', 'type': 'str'},
+ 'marker': {'key': 'Marker', 'type': 'str'},
+ 'max_results': {'key': 'MaxResults', 'type': 'int'},
+ 'segment': {'key': 'Segment', 'type': 'BlobFlatListSegment'},
+ 'next_marker': {'key': 'NextMarker', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'EnumerationResults'
+ }
+
+ def __init__(
+ self,
+ *,
+ service_endpoint: str,
+ container_name: str,
+ segment: "BlobFlatListSegment",
+ prefix: Optional[str] = None,
+ marker: Optional[str] = None,
+ max_results: Optional[int] = None,
+ next_marker: Optional[str] = None,
+ **kwargs
+ ):
+ super(ListBlobsFlatSegmentResponse, self).__init__(**kwargs)
+ self.service_endpoint = service_endpoint
+ self.container_name = container_name
+ self.prefix = prefix
+ self.marker = marker
+ self.max_results = max_results
+ self.segment = segment
+ self.next_marker = next_marker
+
+
+class ListBlobsHierarchySegmentResponse(msrest.serialization.Model):
+ """An enumeration of blobs.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param service_endpoint: Required.
+ :type service_endpoint: str
+ :param container_name: Required.
+ :type container_name: str
+ :param prefix:
+ :type prefix: str
+ :param marker:
+ :type marker: str
+ :param max_results:
+ :type max_results: int
+ :param delimiter:
+ :type delimiter: str
+ :param segment: Required.
+ :type segment: ~azure.storage.blob.models.BlobHierarchyListSegment
+ :param next_marker:
+ :type next_marker: str
+ """
+
+ _validation = {
+ 'service_endpoint': {'required': True},
+ 'container_name': {'required': True},
+ 'segment': {'required': True},
+ }
+
+ _attribute_map = {
+ 'service_endpoint': {'key': 'ServiceEndpoint', 'type': 'str', 'xml': {'attr': True}},
+ 'container_name': {'key': 'ContainerName', 'type': 'str', 'xml': {'attr': True}},
+ 'prefix': {'key': 'Prefix', 'type': 'str'},
+ 'marker': {'key': 'Marker', 'type': 'str'},
+ 'max_results': {'key': 'MaxResults', 'type': 'int'},
+ 'delimiter': {'key': 'Delimiter', 'type': 'str'},
+ 'segment': {'key': 'Segment', 'type': 'BlobHierarchyListSegment'},
+ 'next_marker': {'key': 'NextMarker', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'EnumerationResults'
+ }
+
+ def __init__(
+ self,
+ *,
+ service_endpoint: str,
+ container_name: str,
+ segment: "BlobHierarchyListSegment",
+ prefix: Optional[str] = None,
+ marker: Optional[str] = None,
+ max_results: Optional[int] = None,
+ delimiter: Optional[str] = None,
+ next_marker: Optional[str] = None,
+ **kwargs
+ ):
+ super(ListBlobsHierarchySegmentResponse, self).__init__(**kwargs)
+ self.service_endpoint = service_endpoint
+ self.container_name = container_name
+ self.prefix = prefix
+ self.marker = marker
+ self.max_results = max_results
+ self.delimiter = delimiter
+ self.segment = segment
+ self.next_marker = next_marker
+
+
+class ListContainersSegmentResponse(msrest.serialization.Model):
+ """An enumeration of containers.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param service_endpoint: Required.
+ :type service_endpoint: str
+ :param prefix:
+ :type prefix: str
+ :param marker:
+ :type marker: str
+ :param max_results:
+ :type max_results: int
+ :param container_items: Required.
+ :type container_items: list[~azure.storage.blob.models.ContainerItem]
+ :param next_marker:
+ :type next_marker: str
+ """
+
+ _validation = {
+ 'service_endpoint': {'required': True},
+ 'container_items': {'required': True},
+ }
+
+ _attribute_map = {
+ 'service_endpoint': {'key': 'ServiceEndpoint', 'type': 'str', 'xml': {'attr': True}},
+ 'prefix': {'key': 'Prefix', 'type': 'str'},
+ 'marker': {'key': 'Marker', 'type': 'str'},
+ 'max_results': {'key': 'MaxResults', 'type': 'int'},
+ 'container_items': {'key': 'ContainerItems', 'type': '[ContainerItem]', 'xml': {'name': 'Containers', 'wrapped': True, 'itemsName': 'Container'}},
+ 'next_marker': {'key': 'NextMarker', 'type': 'str'},
+ }
+ _xml_map = {
+ 'name': 'EnumerationResults'
+ }
+
+ def __init__(
+ self,
+ *,
+ service_endpoint: str,
+ container_items: List["ContainerItem"],
+ prefix: Optional[str] = None,
+ marker: Optional[str] = None,
+ max_results: Optional[int] = None,
+ next_marker: Optional[str] = None,
+ **kwargs
+ ):
+ super(ListContainersSegmentResponse, self).__init__(**kwargs)
+ self.service_endpoint = service_endpoint
+ self.prefix = prefix
+ self.marker = marker
+ self.max_results = max_results
+ self.container_items = container_items
+ self.next_marker = next_marker
+
+
+class Logging(msrest.serialization.Model):
+ """Azure Analytics Logging settings.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param version: Required. The version of Storage Analytics to configure.
+ :type version: str
+ :param delete: Required. Indicates whether all delete requests should be logged.
+ :type delete: bool
+ :param read: Required. Indicates whether all read requests should be logged.
+ :type read: bool
+ :param write: Required. Indicates whether all write requests should be logged.
+ :type write: bool
+ :param retention_policy: Required. the retention policy which determines how long the
+ associated data should persist.
+ :type retention_policy: ~azure.storage.blob.models.RetentionPolicy
+ """
+
+ _validation = {
+ 'version': {'required': True},
+ 'delete': {'required': True},
+ 'read': {'required': True},
+ 'write': {'required': True},
+ 'retention_policy': {'required': True},
+ }
+
+ _attribute_map = {
+ 'version': {'key': 'Version', 'type': 'str'},
+ 'delete': {'key': 'Delete', 'type': 'bool'},
+ 'read': {'key': 'Read', 'type': 'bool'},
+ 'write': {'key': 'Write', 'type': 'bool'},
+ 'retention_policy': {'key': 'RetentionPolicy', 'type': 'RetentionPolicy'},
+ }
+
+ def __init__(
+ self,
+ *,
+ version: str,
+ delete: bool,
+ read: bool,
+ write: bool,
+ retention_policy: "RetentionPolicy",
+ **kwargs
+ ):
+ super(Logging, self).__init__(**kwargs)
+ self.version = version
+ self.delete = delete
+ self.read = read
+ self.write = write
+ self.retention_policy = retention_policy
+
+
+class Metrics(msrest.serialization.Model):
+ """a summary of request statistics grouped by API in hour or minute aggregates for blobs.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param version: The version of Storage Analytics to configure.
+ :type version: str
+ :param enabled: Required. Indicates whether metrics are enabled for the Blob service.
+ :type enabled: bool
+ :param include_apis: Indicates whether metrics should generate summary statistics for called
+ API operations.
+ :type include_apis: bool
+ :param retention_policy: the retention policy which determines how long the associated data
+ should persist.
+ :type retention_policy: ~azure.storage.blob.models.RetentionPolicy
+ """
+
+ _validation = {
+ 'enabled': {'required': True},
+ }
+
+ _attribute_map = {
+ 'version': {'key': 'Version', 'type': 'str'},
+ 'enabled': {'key': 'Enabled', 'type': 'bool'},
+ 'include_apis': {'key': 'IncludeAPIs', 'type': 'bool'},
+ 'retention_policy': {'key': 'RetentionPolicy', 'type': 'RetentionPolicy'},
+ }
+
+ def __init__(
+ self,
+ *,
+ enabled: bool,
+ version: Optional[str] = None,
+ include_apis: Optional[bool] = None,
+ retention_policy: Optional["RetentionPolicy"] = None,
+ **kwargs
+ ):
+ super(Metrics, self).__init__(**kwargs)
+ self.version = version
+ self.enabled = enabled
+ self.include_apis = include_apis
+ self.retention_policy = retention_policy
+
+
+class ModifiedAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param if_modified_since: Specify this header value to operate only on a blob if it has been
+ modified since the specified date/time.
+ :type if_modified_since: ~datetime.datetime
+ :param if_unmodified_since: Specify this header value to operate only on a blob if it has not
+ been modified since the specified date/time.
+ :type if_unmodified_since: ~datetime.datetime
+ :param if_match: Specify an ETag value to operate only on blobs with a matching value.
+ :type if_match: str
+ :param if_none_match: Specify an ETag value to operate only on blobs without a matching value.
+ :type if_none_match: str
+ :param if_tags: Specify a SQL where clause on blob tags to operate only on blobs with a
+ matching value.
+ :type if_tags: str
+ """
+
+ _attribute_map = {
+ 'if_modified_since': {'key': 'ifModifiedSince', 'type': 'rfc-1123'},
+ 'if_unmodified_since': {'key': 'ifUnmodifiedSince', 'type': 'rfc-1123'},
+ 'if_match': {'key': 'ifMatch', 'type': 'str'},
+ 'if_none_match': {'key': 'ifNoneMatch', 'type': 'str'},
+ 'if_tags': {'key': 'ifTags', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ if_modified_since: Optional[datetime.datetime] = None,
+ if_unmodified_since: Optional[datetime.datetime] = None,
+ if_match: Optional[str] = None,
+ if_none_match: Optional[str] = None,
+ if_tags: Optional[str] = None,
+ **kwargs
+ ):
+ super(ModifiedAccessConditions, self).__init__(**kwargs)
+ self.if_modified_since = if_modified_since
+ self.if_unmodified_since = if_unmodified_since
+ self.if_match = if_match
+ self.if_none_match = if_none_match
+ self.if_tags = if_tags
+
+
+class PageList(msrest.serialization.Model):
+ """the list of pages.
+
+ :param page_range:
+ :type page_range: list[~azure.storage.blob.models.PageRange]
+ :param clear_range:
+ :type clear_range: list[~azure.storage.blob.models.ClearRange]
+ """
+
+ _attribute_map = {
+ 'page_range': {'key': 'PageRange', 'type': '[PageRange]'},
+ 'clear_range': {'key': 'ClearRange', 'type': '[ClearRange]'},
+ }
+
+ def __init__(
+ self,
+ *,
+ page_range: Optional[List["PageRange"]] = None,
+ clear_range: Optional[List["ClearRange"]] = None,
+ **kwargs
+ ):
+ super(PageList, self).__init__(**kwargs)
+ self.page_range = page_range
+ self.clear_range = clear_range
+
+
+class PageRange(msrest.serialization.Model):
+ """PageRange.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param start: Required.
+ :type start: long
+ :param end: Required.
+ :type end: long
+ """
+
+ _validation = {
+ 'start': {'required': True},
+ 'end': {'required': True},
+ }
+
+ _attribute_map = {
+ 'start': {'key': 'Start', 'type': 'long', 'xml': {'name': 'Start'}},
+ 'end': {'key': 'End', 'type': 'long', 'xml': {'name': 'End'}},
+ }
+ _xml_map = {
+ 'name': 'PageRange'
+ }
+
+ def __init__(
+ self,
+ *,
+ start: int,
+ end: int,
+ **kwargs
+ ):
+ super(PageRange, self).__init__(**kwargs)
+ self.start = start
+ self.end = end
+
+
+class QueryFormat(msrest.serialization.Model):
+ """QueryFormat.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param type: Required. The quick query format type. Possible values include: "delimited",
+ "json", "arrow", "parquet".
+ :type type: str or ~azure.storage.blob.models.QueryFormatType
+ :param delimited_text_configuration: Groups the settings used for interpreting the blob data if
+ the blob is delimited text formatted.
+ :type delimited_text_configuration: ~azure.storage.blob.models.DelimitedTextConfiguration
+ :param json_text_configuration: json text configuration.
+ :type json_text_configuration: ~azure.storage.blob.models.JsonTextConfiguration
+ :param arrow_configuration: Groups the settings used for formatting the response if the
+ response should be Arrow formatted.
+ :type arrow_configuration: ~azure.storage.blob.models.ArrowConfiguration
+ :param parquet_text_configuration: Any object.
+ :type parquet_text_configuration: any
+ """
+
+ _validation = {
+ 'type': {'required': True},
+ }
+
+ _attribute_map = {
+ 'type': {'key': 'Type', 'type': 'str', 'xml': {'name': 'Type'}},
+ 'delimited_text_configuration': {'key': 'DelimitedTextConfiguration', 'type': 'DelimitedTextConfiguration'},
+ 'json_text_configuration': {'key': 'JsonTextConfiguration', 'type': 'JsonTextConfiguration'},
+ 'arrow_configuration': {'key': 'ArrowConfiguration', 'type': 'ArrowConfiguration'},
+ 'parquet_text_configuration': {'key': 'ParquetTextConfiguration', 'type': 'object'},
+ }
+
+ def __init__(
+ self,
+ *,
+ type: Union[str, "QueryFormatType"],
+ delimited_text_configuration: Optional["DelimitedTextConfiguration"] = None,
+ json_text_configuration: Optional["JsonTextConfiguration"] = None,
+ arrow_configuration: Optional["ArrowConfiguration"] = None,
+ parquet_text_configuration: Optional[Any] = None,
+ **kwargs
+ ):
+ super(QueryFormat, self).__init__(**kwargs)
+ self.type = type
+ self.delimited_text_configuration = delimited_text_configuration
+ self.json_text_configuration = json_text_configuration
+ self.arrow_configuration = arrow_configuration
+ self.parquet_text_configuration = parquet_text_configuration
+
+
+class QueryRequest(msrest.serialization.Model):
+ """Groups the set of query request settings.
+
+ Variables are only populated by the server, and will be ignored when sending a request.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :ivar query_type: Required. The type of the provided query expression. Has constant value:
+ "SQL".
+ :vartype query_type: str
+ :param expression: Required. The query expression in SQL. The maximum size of the query
+ expression is 256KiB.
+ :type expression: str
+ :param input_serialization:
+ :type input_serialization: ~azure.storage.blob.models.QuerySerialization
+ :param output_serialization:
+ :type output_serialization: ~azure.storage.blob.models.QuerySerialization
+ """
+
+ _validation = {
+ 'query_type': {'required': True, 'constant': True},
+ 'expression': {'required': True},
+ }
+
+ _attribute_map = {
+ 'query_type': {'key': 'QueryType', 'type': 'str', 'xml': {'name': 'QueryType'}},
+ 'expression': {'key': 'Expression', 'type': 'str', 'xml': {'name': 'Expression'}},
+ 'input_serialization': {'key': 'InputSerialization', 'type': 'QuerySerialization'},
+ 'output_serialization': {'key': 'OutputSerialization', 'type': 'QuerySerialization'},
+ }
+ _xml_map = {
+ 'name': 'QueryRequest'
+ }
+
+ query_type = "SQL"
+
+ def __init__(
+ self,
+ *,
+ expression: str,
+ input_serialization: Optional["QuerySerialization"] = None,
+ output_serialization: Optional["QuerySerialization"] = None,
+ **kwargs
+ ):
+ super(QueryRequest, self).__init__(**kwargs)
+ self.expression = expression
+ self.input_serialization = input_serialization
+ self.output_serialization = output_serialization
+
+
+class QuerySerialization(msrest.serialization.Model):
+ """QuerySerialization.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param format: Required.
+ :type format: ~azure.storage.blob.models.QueryFormat
+ """
+
+ _validation = {
+ 'format': {'required': True},
+ }
+
+ _attribute_map = {
+ 'format': {'key': 'Format', 'type': 'QueryFormat'},
+ }
+
+ def __init__(
+ self,
+ *,
+ format: "QueryFormat",
+ **kwargs
+ ):
+ super(QuerySerialization, self).__init__(**kwargs)
+ self.format = format
+
+
+class RetentionPolicy(msrest.serialization.Model):
+ """the retention policy which determines how long the associated data should persist.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param enabled: Required. Indicates whether a retention policy is enabled for the storage
+ service.
+ :type enabled: bool
+ :param days: Indicates the number of days that metrics or logging or soft-deleted data should
+ be retained. All data older than this value will be deleted.
+ :type days: int
+ :param allow_permanent_delete: Indicates whether permanent delete is allowed on this storage
+ account.
+ :type allow_permanent_delete: bool
+ """
+
+ _validation = {
+ 'enabled': {'required': True},
+ 'days': {'minimum': 1},
+ }
+
+ _attribute_map = {
+ 'enabled': {'key': 'Enabled', 'type': 'bool'},
+ 'days': {'key': 'Days', 'type': 'int'},
+ 'allow_permanent_delete': {'key': 'AllowPermanentDelete', 'type': 'bool'},
+ }
+
+ def __init__(
+ self,
+ *,
+ enabled: bool,
+ days: Optional[int] = None,
+ allow_permanent_delete: Optional[bool] = None,
+ **kwargs
+ ):
+ super(RetentionPolicy, self).__init__(**kwargs)
+ self.enabled = enabled
+ self.days = days
+ self.allow_permanent_delete = allow_permanent_delete
+
+
+class SequenceNumberAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param if_sequence_number_less_than_or_equal_to: Specify this header value to operate only on a
+ blob if it has a sequence number less than or equal to the specified.
+ :type if_sequence_number_less_than_or_equal_to: long
+ :param if_sequence_number_less_than: Specify this header value to operate only on a blob if it
+ has a sequence number less than the specified.
+ :type if_sequence_number_less_than: long
+ :param if_sequence_number_equal_to: Specify this header value to operate only on a blob if it
+ has the specified sequence number.
+ :type if_sequence_number_equal_to: long
+ """
+
+ _attribute_map = {
+ 'if_sequence_number_less_than_or_equal_to': {'key': 'ifSequenceNumberLessThanOrEqualTo', 'type': 'long'},
+ 'if_sequence_number_less_than': {'key': 'ifSequenceNumberLessThan', 'type': 'long'},
+ 'if_sequence_number_equal_to': {'key': 'ifSequenceNumberEqualTo', 'type': 'long'},
+ }
+
+ def __init__(
+ self,
+ *,
+ if_sequence_number_less_than_or_equal_to: Optional[int] = None,
+ if_sequence_number_less_than: Optional[int] = None,
+ if_sequence_number_equal_to: Optional[int] = None,
+ **kwargs
+ ):
+ super(SequenceNumberAccessConditions, self).__init__(**kwargs)
+ self.if_sequence_number_less_than_or_equal_to = if_sequence_number_less_than_or_equal_to
+ self.if_sequence_number_less_than = if_sequence_number_less_than
+ self.if_sequence_number_equal_to = if_sequence_number_equal_to
+
+
+class SignedIdentifier(msrest.serialization.Model):
+ """signed identifier.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param id: Required. a unique id.
+ :type id: str
+ :param access_policy: An Access policy.
+ :type access_policy: ~azure.storage.blob.models.AccessPolicy
+ """
+
+ _validation = {
+ 'id': {'required': True},
+ }
+
+ _attribute_map = {
+ 'id': {'key': 'Id', 'type': 'str'},
+ 'access_policy': {'key': 'AccessPolicy', 'type': 'AccessPolicy'},
+ }
+ _xml_map = {
+ 'name': 'SignedIdentifier'
+ }
+
+ def __init__(
+ self,
+ *,
+ id: str,
+ access_policy: Optional["AccessPolicy"] = None,
+ **kwargs
+ ):
+ super(SignedIdentifier, self).__init__(**kwargs)
+ self.id = id
+ self.access_policy = access_policy
+
+
+class SourceModifiedAccessConditions(msrest.serialization.Model):
+ """Parameter group.
+
+ :param source_if_modified_since: Specify this header value to operate only on a blob if it has
+ been modified since the specified date/time.
+ :type source_if_modified_since: ~datetime.datetime
+ :param source_if_unmodified_since: Specify this header value to operate only on a blob if it
+ has not been modified since the specified date/time.
+ :type source_if_unmodified_since: ~datetime.datetime
+ :param source_if_match: Specify an ETag value to operate only on blobs with a matching value.
+ :type source_if_match: str
+ :param source_if_none_match: Specify an ETag value to operate only on blobs without a matching
+ value.
+ :type source_if_none_match: str
+ :param source_if_tags: Specify a SQL where clause on blob tags to operate only on blobs with a
+ matching value.
+ :type source_if_tags: str
+ """
+
+ _attribute_map = {
+ 'source_if_modified_since': {'key': 'sourceIfModifiedSince', 'type': 'rfc-1123'},
+ 'source_if_unmodified_since': {'key': 'sourceIfUnmodifiedSince', 'type': 'rfc-1123'},
+ 'source_if_match': {'key': 'sourceIfMatch', 'type': 'str'},
+ 'source_if_none_match': {'key': 'sourceIfNoneMatch', 'type': 'str'},
+ 'source_if_tags': {'key': 'sourceIfTags', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ source_if_modified_since: Optional[datetime.datetime] = None,
+ source_if_unmodified_since: Optional[datetime.datetime] = None,
+ source_if_match: Optional[str] = None,
+ source_if_none_match: Optional[str] = None,
+ source_if_tags: Optional[str] = None,
+ **kwargs
+ ):
+ super(SourceModifiedAccessConditions, self).__init__(**kwargs)
+ self.source_if_modified_since = source_if_modified_since
+ self.source_if_unmodified_since = source_if_unmodified_since
+ self.source_if_match = source_if_match
+ self.source_if_none_match = source_if_none_match
+ self.source_if_tags = source_if_tags
+
+
+class StaticWebsite(msrest.serialization.Model):
+ """The properties that enable an account to host a static website.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param enabled: Required. Indicates whether this account is hosting a static website.
+ :type enabled: bool
+ :param index_document: The default name of the index page under each directory.
+ :type index_document: str
+ :param error_document404_path: The absolute path of the custom 404 page.
+ :type error_document404_path: str
+ :param default_index_document_path: Absolute path of the default index page.
+ :type default_index_document_path: str
+ """
+
+ _validation = {
+ 'enabled': {'required': True},
+ }
+
+ _attribute_map = {
+ 'enabled': {'key': 'Enabled', 'type': 'bool'},
+ 'index_document': {'key': 'IndexDocument', 'type': 'str'},
+ 'error_document404_path': {'key': 'ErrorDocument404Path', 'type': 'str'},
+ 'default_index_document_path': {'key': 'DefaultIndexDocumentPath', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ enabled: bool,
+ index_document: Optional[str] = None,
+ error_document404_path: Optional[str] = None,
+ default_index_document_path: Optional[str] = None,
+ **kwargs
+ ):
+ super(StaticWebsite, self).__init__(**kwargs)
+ self.enabled = enabled
+ self.index_document = index_document
+ self.error_document404_path = error_document404_path
+ self.default_index_document_path = default_index_document_path
+
+
+class StorageError(msrest.serialization.Model):
+ """StorageError.
+
+ :param message:
+ :type message: str
+ """
+
+ _attribute_map = {
+ 'message': {'key': 'Message', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ message: Optional[str] = None,
+ **kwargs
+ ):
+ super(StorageError, self).__init__(**kwargs)
+ self.message = message
+
+
+class StorageServiceProperties(msrest.serialization.Model):
+ """Storage Service Properties.
+
+ :param logging: Azure Analytics Logging settings.
+ :type logging: ~azure.storage.blob.models.Logging
+ :param hour_metrics: a summary of request statistics grouped by API in hour or minute
+ aggregates for blobs.
+ :type hour_metrics: ~azure.storage.blob.models.Metrics
+ :param minute_metrics: a summary of request statistics grouped by API in hour or minute
+ aggregates for blobs.
+ :type minute_metrics: ~azure.storage.blob.models.Metrics
+ :param cors: The set of CORS rules.
+ :type cors: list[~azure.storage.blob.models.CorsRule]
+ :param default_service_version: The default version to use for requests to the Blob service if
+ an incoming request's version is not specified. Possible values include version 2008-10-27 and
+ all more recent versions.
+ :type default_service_version: str
+ :param delete_retention_policy: the retention policy which determines how long the associated
+ data should persist.
+ :type delete_retention_policy: ~azure.storage.blob.models.RetentionPolicy
+ :param static_website: The properties that enable an account to host a static website.
+ :type static_website: ~azure.storage.blob.models.StaticWebsite
+ """
+
+ _attribute_map = {
+ 'logging': {'key': 'Logging', 'type': 'Logging'},
+ 'hour_metrics': {'key': 'HourMetrics', 'type': 'Metrics'},
+ 'minute_metrics': {'key': 'MinuteMetrics', 'type': 'Metrics'},
+ 'cors': {'key': 'Cors', 'type': '[CorsRule]', 'xml': {'wrapped': True}},
+ 'default_service_version': {'key': 'DefaultServiceVersion', 'type': 'str'},
+ 'delete_retention_policy': {'key': 'DeleteRetentionPolicy', 'type': 'RetentionPolicy'},
+ 'static_website': {'key': 'StaticWebsite', 'type': 'StaticWebsite'},
+ }
+
+ def __init__(
+ self,
+ *,
+ logging: Optional["Logging"] = None,
+ hour_metrics: Optional["Metrics"] = None,
+ minute_metrics: Optional["Metrics"] = None,
+ cors: Optional[List["CorsRule"]] = None,
+ default_service_version: Optional[str] = None,
+ delete_retention_policy: Optional["RetentionPolicy"] = None,
+ static_website: Optional["StaticWebsite"] = None,
+ **kwargs
+ ):
+ super(StorageServiceProperties, self).__init__(**kwargs)
+ self.logging = logging
+ self.hour_metrics = hour_metrics
+ self.minute_metrics = minute_metrics
+ self.cors = cors
+ self.default_service_version = default_service_version
+ self.delete_retention_policy = delete_retention_policy
+ self.static_website = static_website
+
+
+class StorageServiceStats(msrest.serialization.Model):
+ """Stats for the storage service.
+
+ :param geo_replication: Geo-Replication information for the Secondary Storage Service.
+ :type geo_replication: ~azure.storage.blob.models.GeoReplication
+ """
+
+ _attribute_map = {
+ 'geo_replication': {'key': 'GeoReplication', 'type': 'GeoReplication'},
+ }
+
+ def __init__(
+ self,
+ *,
+ geo_replication: Optional["GeoReplication"] = None,
+ **kwargs
+ ):
+ super(StorageServiceStats, self).__init__(**kwargs)
+ self.geo_replication = geo_replication
+
+
+class UserDelegationKey(msrest.serialization.Model):
+ """A user delegation key.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param signed_oid: Required. The Azure Active Directory object ID in GUID format.
+ :type signed_oid: str
+ :param signed_tid: Required. The Azure Active Directory tenant ID in GUID format.
+ :type signed_tid: str
+ :param signed_start: Required. The date-time the key is active.
+ :type signed_start: ~datetime.datetime
+ :param signed_expiry: Required. The date-time the key expires.
+ :type signed_expiry: ~datetime.datetime
+ :param signed_service: Required. Abbreviation of the Azure Storage service that accepts the
+ key.
+ :type signed_service: str
+ :param signed_version: Required. The service version that created the key.
+ :type signed_version: str
+ :param value: Required. The key as a base64 string.
+ :type value: str
+ """
+
+ _validation = {
+ 'signed_oid': {'required': True},
+ 'signed_tid': {'required': True},
+ 'signed_start': {'required': True},
+ 'signed_expiry': {'required': True},
+ 'signed_service': {'required': True},
+ 'signed_version': {'required': True},
+ 'value': {'required': True},
+ }
+
+ _attribute_map = {
+ 'signed_oid': {'key': 'SignedOid', 'type': 'str'},
+ 'signed_tid': {'key': 'SignedTid', 'type': 'str'},
+ 'signed_start': {'key': 'SignedStart', 'type': 'iso-8601'},
+ 'signed_expiry': {'key': 'SignedExpiry', 'type': 'iso-8601'},
+ 'signed_service': {'key': 'SignedService', 'type': 'str'},
+ 'signed_version': {'key': 'SignedVersion', 'type': 'str'},
+ 'value': {'key': 'Value', 'type': 'str'},
+ }
+
+ def __init__(
+ self,
+ *,
+ signed_oid: str,
+ signed_tid: str,
+ signed_start: datetime.datetime,
+ signed_expiry: datetime.datetime,
+ signed_service: str,
+ signed_version: str,
+ value: str,
+ **kwargs
+ ):
+ super(UserDelegationKey, self).__init__(**kwargs)
+ self.signed_oid = signed_oid
+ self.signed_tid = signed_tid
+ self.signed_start = signed_start
+ self.signed_expiry = signed_expiry
+ self.signed_service = signed_service
+ self.signed_version = signed_version
+ self.value = value
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/__init__.py
new file mode 100644
index 00000000000..902269d05ed
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/__init__.py
@@ -0,0 +1,23 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+
+from ._service_operations import ServiceOperations
+from ._container_operations import ContainerOperations
+from ._blob_operations import BlobOperations
+from ._page_blob_operations import PageBlobOperations
+from ._append_blob_operations import AppendBlobOperations
+from ._block_blob_operations import BlockBlobOperations
+
+__all__ = [
+ 'ServiceOperations',
+ 'ContainerOperations',
+ 'BlobOperations',
+ 'PageBlobOperations',
+ 'AppendBlobOperations',
+ 'BlockBlobOperations',
+]
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_append_blob_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_append_blob_operations.py
new file mode 100644
index 00000000000..b38af4b94f1
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_append_blob_operations.py
@@ -0,0 +1,734 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import TYPE_CHECKING
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import HttpRequest, HttpResponse
+
+from .. import models as _models
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import,ungrouped-imports
+ from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union
+
+ T = TypeVar('T')
+ ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
+
+class AppendBlobOperations(object):
+ """AppendBlobOperations operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer):
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ def create(
+ self,
+ content_length, # type: int
+ timeout=None, # type: Optional[int]
+ metadata=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ blob_tags_string=None, # type: Optional[str]
+ immutability_policy_expiry=None, # type: Optional[datetime.datetime]
+ immutability_policy_mode=None, # type: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]]
+ legal_hold=None, # type: Optional[bool]
+ blob_http_headers=None, # type: Optional["_models.BlobHTTPHeaders"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Create Append Blob operation creates a new append blob.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _blob_cache_control = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if blob_http_headers is not None:
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ blob_type = "AppendBlob"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.create.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ create.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def append_block(
+ self,
+ content_length, # type: int
+ body, # type: IO
+ timeout=None, # type: Optional[int]
+ transactional_content_md5=None, # type: Optional[bytearray]
+ transactional_content_crc64=None, # type: Optional[bytearray]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ append_position_access_conditions=None, # type: Optional["_models.AppendPositionAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Append Block operation commits a new block of data to the end of an existing append blob.
+ The Append Block operation is permitted only if the blob was created with x-ms-blob-type set to
+ AppendBlob. Append Block is supported only on version 2015-02-21 version or later.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param body: Initial data.
+ :type body: IO
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param append_position_access_conditions: Parameter group.
+ :type append_position_access_conditions: ~azure.storage.blob.models.AppendPositionAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _max_size = None
+ _append_position = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if append_position_access_conditions is not None:
+ _max_size = append_position_access_conditions.max_size
+ _append_position = append_position_access_conditions.append_position
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "appendblock"
+ content_type = kwargs.pop("content_type", "application/octet-stream")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.append_block.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _max_size is not None:
+ header_parameters['x-ms-blob-condition-maxsize'] = self._serialize.header("max_size", _max_size, 'long')
+ if _append_position is not None:
+ header_parameters['x-ms-blob-condition-appendpos'] = self._serialize.header("append_position", _append_position, 'long')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content_kwargs['stream_content'] = body
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-append-offset']=self._deserialize('str', response.headers.get('x-ms-blob-append-offset'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ append_block.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def append_block_from_url(
+ self,
+ source_url, # type: str
+ content_length, # type: int
+ source_range=None, # type: Optional[str]
+ source_content_md5=None, # type: Optional[bytearray]
+ source_contentcrc64=None, # type: Optional[bytearray]
+ timeout=None, # type: Optional[int]
+ transactional_content_md5=None, # type: Optional[bytearray]
+ request_id_parameter=None, # type: Optional[str]
+ copy_source_authorization=None, # type: Optional[str]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ append_position_access_conditions=None, # type: Optional["_models.AppendPositionAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ source_modified_access_conditions=None, # type: Optional["_models.SourceModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Append Block operation commits a new block of data to the end of an existing append blob
+ where the contents are read from a source url. The Append Block operation is permitted only if
+ the blob was created with x-ms-blob-type set to AppendBlob. Append Block is supported only on
+ version 2015-02-21 version or later.
+
+ :param source_url: Specify a URL to the copy source.
+ :type source_url: str
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param source_range: Bytes of source data in the specified range.
+ :type source_range: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param source_contentcrc64: Specify the crc64 calculated for the range of bytes that must be
+ read from the copy source.
+ :type source_contentcrc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param append_position_access_conditions: Parameter group.
+ :type append_position_access_conditions: ~azure.storage.blob.models.AppendPositionAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _lease_id = None
+ _max_size = None
+ _append_position = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ if append_position_access_conditions is not None:
+ _max_size = append_position_access_conditions.max_size
+ _append_position = append_position_access_conditions.append_position
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ comp = "appendblock"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.append_block_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-copy-source'] = self._serialize.header("source_url", source_url, 'str')
+ if source_range is not None:
+ header_parameters['x-ms-source-range'] = self._serialize.header("source_range", source_range, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if source_contentcrc64 is not None:
+ header_parameters['x-ms-source-content-crc64'] = self._serialize.header("source_contentcrc64", source_contentcrc64, 'bytearray')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _max_size is not None:
+ header_parameters['x-ms-blob-condition-maxsize'] = self._serialize.header("max_size", _max_size, 'long')
+ if _append_position is not None:
+ header_parameters['x-ms-blob-condition-appendpos'] = self._serialize.header("append_position", _append_position, 'long')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-append-offset']=self._deserialize('str', response.headers.get('x-ms-blob-append-offset'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ append_block_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def seal(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ append_position_access_conditions=None, # type: Optional["_models.AppendPositionAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Seal operation seals the Append Blob to make it read-only. Seal is supported only on
+ version 2019-12-12 version or later.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param append_position_access_conditions: Parameter group.
+ :type append_position_access_conditions: ~azure.storage.blob.models.AppendPositionAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _append_position = None
+ if append_position_access_conditions is not None:
+ _append_position = append_position_access_conditions.append_position
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ comp = "seal"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.seal.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _append_position is not None:
+ header_parameters['x-ms-blob-condition-appendpos'] = self._serialize.header("append_position", _append_position, 'long')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-sealed']=self._deserialize('bool', response.headers.get('x-ms-blob-sealed'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ seal.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_blob_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_blob_operations.py
new file mode 100644
index 00000000000..e041221239f
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_blob_operations.py
@@ -0,0 +1,3036 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import TYPE_CHECKING
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import HttpRequest, HttpResponse
+
+from .. import models as _models
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import,ungrouped-imports
+ from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union
+
+ T = TypeVar('T')
+ ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
+
+class BlobOperations(object):
+ """BlobOperations operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer):
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ def download(
+ self,
+ snapshot=None, # type: Optional[str]
+ version_id=None, # type: Optional[str]
+ timeout=None, # type: Optional[int]
+ range=None, # type: Optional[str]
+ range_get_content_md5=None, # type: Optional[bool]
+ range_get_content_crc64=None, # type: Optional[bool]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> IO
+ """The Download operation reads or downloads a blob from the system, including its metadata and
+ properties. You can also call Download to read a snapshot.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param range_get_content_md5: When set to true and specified together with the Range, the
+ service returns the MD5 hash for the range, as long as the range is less than or equal to 4 MB
+ in size.
+ :type range_get_content_md5: bool
+ :param range_get_content_crc64: When set to true and specified together with the Range, the
+ service returns the CRC64 hash for the range, as long as the range is less than or equal to 4
+ MB in size.
+ :type range_get_content_crc64: bool
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: IO, or the result of cls(response)
+ :rtype: IO
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[IO]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.download.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if range_get_content_md5 is not None:
+ header_parameters['x-ms-range-get-content-md5'] = self._serialize.header("range_get_content_md5", range_get_content_md5, 'bool')
+ if range_get_content_crc64 is not None:
+ header_parameters['x-ms-range-get-content-crc64'] = self._serialize.header("range_get_content_crc64", range_get_content_crc64, 'bool')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=True, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200, 206]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ if response.status_code == 200:
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['x-ms-or-policy-id']=self._deserialize('str', response.headers.get('x-ms-or-policy-id'))
+ response_headers['x-ms-or']=self._deserialize('str', response.headers.get('x-ms-or'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['Content-Range']=self._deserialize('str', response.headers.get('Content-Range'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['x-ms-is-current-version']=self._deserialize('bool', response.headers.get('x-ms-is-current-version'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-blob-content-md5']=self._deserialize('bytearray', response.headers.get('x-ms-blob-content-md5'))
+ response_headers['x-ms-tag-count']=self._deserialize('long', response.headers.get('x-ms-tag-count'))
+ response_headers['x-ms-blob-sealed']=self._deserialize('bool', response.headers.get('x-ms-blob-sealed'))
+ response_headers['x-ms-last-access-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-last-access-time'))
+ response_headers['x-ms-immutability-policy-until-date']=self._deserialize('rfc-1123', response.headers.get('x-ms-immutability-policy-until-date'))
+ response_headers['x-ms-immutability-policy-mode']=self._deserialize('str', response.headers.get('x-ms-immutability-policy-mode'))
+ response_headers['x-ms-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-legal-hold'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if response.status_code == 206:
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['x-ms-or-policy-id']=self._deserialize('str', response.headers.get('x-ms-or-policy-id'))
+ response_headers['x-ms-or']=self._deserialize('str', response.headers.get('x-ms-or'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['Content-Range']=self._deserialize('str', response.headers.get('Content-Range'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['x-ms-is-current-version']=self._deserialize('bool', response.headers.get('x-ms-is-current-version'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-blob-content-md5']=self._deserialize('bytearray', response.headers.get('x-ms-blob-content-md5'))
+ response_headers['x-ms-tag-count']=self._deserialize('long', response.headers.get('x-ms-tag-count'))
+ response_headers['x-ms-blob-sealed']=self._deserialize('bool', response.headers.get('x-ms-blob-sealed'))
+ response_headers['x-ms-last-access-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-last-access-time'))
+ response_headers['x-ms-immutability-policy-until-date']=self._deserialize('rfc-1123', response.headers.get('x-ms-immutability-policy-until-date'))
+ response_headers['x-ms-immutability-policy-mode']=self._deserialize('str', response.headers.get('x-ms-immutability-policy-mode'))
+ response_headers['x-ms-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-legal-hold'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ download.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def get_properties(
+ self,
+ snapshot=None, # type: Optional[str]
+ version_id=None, # type: Optional[str]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Get Properties operation returns all user-defined metadata, standard HTTP properties, and
+ system properties for the blob. It does not return the content of the blob.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_properties.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.head(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-creation-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-creation-time'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['x-ms-or-policy-id']=self._deserialize('str', response.headers.get('x-ms-or-policy-id'))
+ response_headers['x-ms-or']=self._deserialize('str', response.headers.get('x-ms-or'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-incremental-copy']=self._deserialize('bool', response.headers.get('x-ms-incremental-copy'))
+ response_headers['x-ms-copy-destination-snapshot']=self._deserialize('str', response.headers.get('x-ms-copy-destination-snapshot'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-access-tier']=self._deserialize('str', response.headers.get('x-ms-access-tier'))
+ response_headers['x-ms-access-tier-inferred']=self._deserialize('bool', response.headers.get('x-ms-access-tier-inferred'))
+ response_headers['x-ms-archive-status']=self._deserialize('str', response.headers.get('x-ms-archive-status'))
+ response_headers['x-ms-access-tier-change-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-access-tier-change-time'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['x-ms-is-current-version']=self._deserialize('bool', response.headers.get('x-ms-is-current-version'))
+ response_headers['x-ms-tag-count']=self._deserialize('long', response.headers.get('x-ms-tag-count'))
+ response_headers['x-ms-expiry-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-expiry-time'))
+ response_headers['x-ms-blob-sealed']=self._deserialize('bool', response.headers.get('x-ms-blob-sealed'))
+ response_headers['x-ms-rehydrate-priority']=self._deserialize('str', response.headers.get('x-ms-rehydrate-priority'))
+ response_headers['x-ms-last-access-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-last-access-time'))
+ response_headers['x-ms-immutability-policy-until-date']=self._deserialize('rfc-1123', response.headers.get('x-ms-immutability-policy-until-date'))
+ response_headers['x-ms-immutability-policy-mode']=self._deserialize('str', response.headers.get('x-ms-immutability-policy-mode'))
+ response_headers['x-ms-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-legal-hold'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_properties.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def delete(
+ self,
+ snapshot=None, # type: Optional[str]
+ version_id=None, # type: Optional[str]
+ timeout=None, # type: Optional[int]
+ delete_snapshots=None, # type: Optional[Union[str, "_models.DeleteSnapshotsOptionType"]]
+ request_id_parameter=None, # type: Optional[str]
+ blob_delete_type="Permanent", # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """If the storage account's soft delete feature is disabled then, when a blob is deleted, it is
+ permanently removed from the storage account. If the storage account's soft delete feature is
+ enabled, then, when a blob is deleted, it is marked for deletion and becomes inaccessible
+ immediately. However, the blob service retains the blob or snapshot for the number of days
+ specified by the DeleteRetentionPolicy section of [Storage service properties]
+ (Set-Blob-Service-Properties.md). After the specified number of days has passed, the blob's
+ data is permanently removed from the storage account. Note that you continue to be charged for
+ the soft-deleted blob's storage until it is permanently removed. Use the List Blobs API and
+ specify the "include=deleted" query parameter to discover which blobs and snapshots have been
+ soft deleted. You can then use the Undelete Blob API to restore a soft-deleted blob. All other
+ operations on a soft-deleted blob or snapshot causes the service to return an HTTP status code
+ of 404 (ResourceNotFound).
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param delete_snapshots: Required if the blob has associated snapshots. Specify one of the
+ following two options: include: Delete the base blob and all of its snapshots. only: Delete
+ only the blob's snapshots and not the blob itself.
+ :type delete_snapshots: str or ~azure.storage.blob.models.DeleteSnapshotsOptionType
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_delete_type: Optional. Only possible value is 'permanent', which specifies to
+ permanently delete a blob if blob soft delete is enabled.
+ :type blob_delete_type: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.delete.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if blob_delete_type is not None:
+ query_parameters['deletetype'] = self._serialize.query("blob_delete_type", blob_delete_type, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if delete_snapshots is not None:
+ header_parameters['x-ms-delete-snapshots'] = self._serialize.header("delete_snapshots", delete_snapshots, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.delete(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ delete.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def undelete(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Undelete a blob that was previously soft deleted.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "undelete"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.undelete.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ undelete.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def set_expiry(
+ self,
+ expiry_options, # type: Union[str, "_models.BlobExpiryOptions"]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ expires_on=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Sets the time a blob will expire and be deleted.
+
+ :param expiry_options: Required. Indicates mode of the expiry time.
+ :type expiry_options: str or ~azure.storage.blob.models.BlobExpiryOptions
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param expires_on: The time to set the blob to expiry.
+ :type expires_on: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "expiry"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_expiry.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['x-ms-expiry-option'] = self._serialize.header("expiry_options", expiry_options, 'str')
+ if expires_on is not None:
+ header_parameters['x-ms-expiry-time'] = self._serialize.header("expires_on", expires_on, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_expiry.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def set_http_headers(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ blob_http_headers=None, # type: Optional["_models.BlobHTTPHeaders"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Set HTTP Headers operation sets system properties on the blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_cache_control = None
+ _blob_content_type = None
+ _blob_content_md5 = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _blob_content_disposition = None
+ if blob_http_headers is not None:
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_http_headers.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_http_headers.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def set_immutability_policy(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ immutability_policy_expiry=None, # type: Optional[datetime.datetime]
+ immutability_policy_mode=None, # type: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Set Immutability Policy operation sets the immutability policy on the blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "immutabilityPolicies"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_immutability_policy.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-immutability-policy-until-date']=self._deserialize('rfc-1123', response.headers.get('x-ms-immutability-policy-until-date'))
+ response_headers['x-ms-immutability-policy-mode']=self._deserialize('str', response.headers.get('x-ms-immutability-policy-mode'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_immutability_policy.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def delete_immutability_policy(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Delete Immutability Policy operation deletes the immutability policy on the blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "immutabilityPolicies"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.delete_immutability_policy.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.delete(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ delete_immutability_policy.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def set_legal_hold(
+ self,
+ legal_hold, # type: bool
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Set Legal Hold operation sets a legal hold on the blob.
+
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "legalhold"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_legal_hold.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-legal-hold'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_legal_hold.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def set_metadata(
+ self,
+ timeout=None, # type: Optional[int]
+ metadata=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Set Blob Metadata operation sets user-defined metadata for the specified blob as one or
+ more name-value pairs.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "metadata"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_metadata.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_metadata.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def acquire_lease(
+ self,
+ timeout=None, # type: Optional[int]
+ duration=None, # type: Optional[int]
+ proposed_lease_id=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param duration: Specifies the duration of the lease, in seconds, or negative one (-1) for a
+ lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease
+ duration cannot be changed using renew or change.
+ :type duration: int
+ :param proposed_lease_id: Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid
+ Constructor (String) for a list of valid GUID string formats.
+ :type proposed_lease_id: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "acquire"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.acquire_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ if duration is not None:
+ header_parameters['x-ms-lease-duration'] = self._serialize.header("duration", duration, 'int')
+ if proposed_lease_id is not None:
+ header_parameters['x-ms-proposed-lease-id'] = self._serialize.header("proposed_lease_id", proposed_lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ acquire_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def release_lease(
+ self,
+ lease_id, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "release"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.release_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ release_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def renew_lease(
+ self,
+ lease_id, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "renew"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.renew_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ renew_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def change_lease(
+ self,
+ lease_id, # type: str
+ proposed_lease_id, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param proposed_lease_id: Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid
+ Constructor (String) for a list of valid GUID string formats.
+ :type proposed_lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "change"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.change_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ header_parameters['x-ms-proposed-lease-id'] = self._serialize.header("proposed_lease_id", proposed_lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ change_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def break_lease(
+ self,
+ timeout=None, # type: Optional[int]
+ break_period=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
+ operations.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param break_period: For a break operation, proposed duration the lease should continue before
+ it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter
+ than the time remaining on the lease. If longer, the time remaining on the lease is used. A new
+ lease will not be available before the break period has expired, but the lease may be held for
+ longer than the break period. If this header does not appear with a break operation, a
+ fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease
+ breaks immediately.
+ :type break_period: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "lease"
+ action = "break"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.break_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ if break_period is not None:
+ header_parameters['x-ms-lease-break-period'] = self._serialize.header("break_period", break_period, 'int')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-time']=self._deserialize('int', response.headers.get('x-ms-lease-time'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ break_lease.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def create_snapshot(
+ self,
+ timeout=None, # type: Optional[int]
+ metadata=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Create Snapshot operation creates a read-only snapshot of a blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _lease_id = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "snapshot"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.create_snapshot.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-snapshot']=self._deserialize('str', response.headers.get('x-ms-snapshot'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ create_snapshot.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def start_copy_from_url(
+ self,
+ copy_source, # type: str
+ timeout=None, # type: Optional[int]
+ metadata=None, # type: Optional[str]
+ tier=None, # type: Optional[Union[str, "_models.AccessTierOptional"]]
+ rehydrate_priority=None, # type: Optional[Union[str, "_models.RehydratePriority"]]
+ request_id_parameter=None, # type: Optional[str]
+ blob_tags_string=None, # type: Optional[str]
+ seal_blob=None, # type: Optional[bool]
+ immutability_policy_expiry=None, # type: Optional[datetime.datetime]
+ immutability_policy_mode=None, # type: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]]
+ legal_hold=None, # type: Optional[bool]
+ source_modified_access_conditions=None, # type: Optional["_models.SourceModifiedAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Start Copy From URL operation copies a blob or an internet resource to a new blob.
+
+ :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
+ up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
+ would appear in a request URI. The source blob must either be public or must be authenticated
+ via a shared access signature.
+ :type copy_source: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param rehydrate_priority: Optional: Indicates the priority with which to rehydrate an archived
+ blob.
+ :type rehydrate_priority: str or ~azure.storage.blob.models.RehydratePriority
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param seal_blob: Overrides the sealed state of the destination blob. Service version
+ 2019-12-12 and newer.
+ :type seal_blob: bool
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ _source_if_tags = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ _source_if_tags = source_modified_access_conditions.source_if_tags
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.start_copy_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if rehydrate_priority is not None:
+ header_parameters['x-ms-rehydrate-priority'] = self._serialize.header("rehydrate_priority", rehydrate_priority, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ if _source_if_tags is not None:
+ header_parameters['x-ms-source-if-tags'] = self._serialize.header("source_if_tags", _source_if_tags, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if seal_blob is not None:
+ header_parameters['x-ms-seal-blob'] = self._serialize.header("seal_blob", seal_blob, 'bool')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ start_copy_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def copy_from_url(
+ self,
+ copy_source, # type: str
+ timeout=None, # type: Optional[int]
+ metadata=None, # type: Optional[str]
+ tier=None, # type: Optional[Union[str, "_models.AccessTierOptional"]]
+ request_id_parameter=None, # type: Optional[str]
+ source_content_md5=None, # type: Optional[bytearray]
+ blob_tags_string=None, # type: Optional[str]
+ immutability_policy_expiry=None, # type: Optional[datetime.datetime]
+ immutability_policy_mode=None, # type: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]]
+ legal_hold=None, # type: Optional[bool]
+ copy_source_authorization=None, # type: Optional[str]
+ source_modified_access_conditions=None, # type: Optional["_models.SourceModifiedAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Copy From URL operation copies a blob or an internet resource to a new blob. It will not
+ return a response until the copy is complete.
+
+ :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
+ up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
+ would appear in a request URI. The source blob must either be public or must be authenticated
+ via a shared access signature.
+ :type copy_source: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _lease_id = None
+ _encryption_scope = None
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ x_ms_requires_sync = "true"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.copy_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-requires-sync'] = self._serialize.header("x_ms_requires_sync", x_ms_requires_sync, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ copy_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def abort_copy_from_url(
+ self,
+ copy_id, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a
+ destination blob with zero length and full metadata.
+
+ :param copy_id: The copy identifier provided in the x-ms-copy-id header of the original Copy
+ Blob operation.
+ :type copy_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ comp = "copy"
+ copy_action_abort_constant = "abort"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.abort_copy_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['copyid'] = self._serialize.query("copy_id", copy_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-copy-action'] = self._serialize.header("copy_action_abort_constant", copy_action_abort_constant, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [204]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ abort_copy_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def set_tier(
+ self,
+ tier, # type: Union[str, "_models.AccessTierRequired"]
+ snapshot=None, # type: Optional[str]
+ version_id=None, # type: Optional[str]
+ timeout=None, # type: Optional[int]
+ rehydrate_priority=None, # type: Optional[Union[str, "_models.RehydratePriority"]]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Set Tier operation sets the tier on a blob. The operation is allowed on a page blob in a
+ premium storage account and on a block blob in a blob storage account (locally redundant
+ storage only). A premium page blob's tier determines the allowed size, IOPS, and bandwidth of
+ the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation does not
+ update the blob's ETag.
+
+ :param tier: Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierRequired
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param rehydrate_priority: Optional: Indicates the priority with which to rehydrate an archived
+ blob.
+ :type rehydrate_priority: str or ~azure.storage.blob.models.RehydratePriority
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_tags = modified_access_conditions.if_tags
+ comp = "tier"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_tier.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if rehydrate_priority is not None:
+ header_parameters['x-ms-rehydrate-priority'] = self._serialize.header("rehydrate_priority", rehydrate_priority, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200, 202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ if response.status_code == 200:
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+
+ if response.status_code == 202:
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_tier.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def get_account_info(
+ self,
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Returns the sku name and account kind.
+
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "account"
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_account_info.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-sku-name']=self._deserialize('str', response.headers.get('x-ms-sku-name'))
+ response_headers['x-ms-account-kind']=self._deserialize('str', response.headers.get('x-ms-account-kind'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_account_info.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def query(
+ self,
+ snapshot=None, # type: Optional[str]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ query_request=None, # type: Optional["_models.QueryRequest"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> IO
+ """The Query operation enables users to select/project on blob data by providing simple query
+ expressions.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param query_request: the query request.
+ :type query_request: ~azure.storage.blob.models.QueryRequest
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: IO, or the result of cls(response)
+ :rtype: IO
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[IO]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "query"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.query.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ if query_request is not None:
+ body_content = self._serialize.body(query_request, 'QueryRequest', is_xml=True)
+ else:
+ body_content = None
+ body_content_kwargs['content'] = body_content
+ request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=True, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200, 206]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ if response.status_code == 200:
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['Content-Range']=self._deserialize('str', response.headers.get('Content-Range'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-blob-content-md5']=self._deserialize('bytearray', response.headers.get('x-ms-blob-content-md5'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if response.status_code == 206:
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['Content-Length']=self._deserialize('long', response.headers.get('Content-Length'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['Content-Range']=self._deserialize('str', response.headers.get('Content-Range'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['Content-Encoding']=self._deserialize('str', response.headers.get('Content-Encoding'))
+ response_headers['Cache-Control']=self._deserialize('str', response.headers.get('Cache-Control'))
+ response_headers['Content-Disposition']=self._deserialize('str', response.headers.get('Content-Disposition'))
+ response_headers['Content-Language']=self._deserialize('str', response.headers.get('Content-Language'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-blob-type']=self._deserialize('str', response.headers.get('x-ms-blob-type'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-copy-completion-time']=self._deserialize('rfc-1123', response.headers.get('x-ms-copy-completion-time'))
+ response_headers['x-ms-copy-status-description']=self._deserialize('str', response.headers.get('x-ms-copy-status-description'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-progress']=self._deserialize('str', response.headers.get('x-ms-copy-progress'))
+ response_headers['x-ms-copy-source']=self._deserialize('str', response.headers.get('x-ms-copy-source'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Accept-Ranges']=self._deserialize('str', response.headers.get('Accept-Ranges'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-committed-block-count']=self._deserialize('int', response.headers.get('x-ms-blob-committed-block-count'))
+ response_headers['x-ms-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+ response_headers['x-ms-blob-content-md5']=self._deserialize('bytearray', response.headers.get('x-ms-blob-content-md5'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ query.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def get_tags(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ snapshot=None, # type: Optional[str]
+ version_id=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.BlobTags"
+ """The Get Tags operation enables users to get the tags associated with a blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: BlobTags, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.BlobTags
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.BlobTags"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_tags = None
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_tags = modified_access_conditions.if_tags
+ comp = "tags"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_tags.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('BlobTags', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_tags.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def set_tags(
+ self,
+ timeout=None, # type: Optional[int]
+ version_id=None, # type: Optional[str]
+ transactional_content_md5=None, # type: Optional[bytearray]
+ transactional_content_crc64=None, # type: Optional[bytearray]
+ request_id_parameter=None, # type: Optional[str]
+ tags=None, # type: Optional["_models.BlobTags"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Set Tags operation enables users to set tags on a blob.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param version_id: The version id parameter is an opaque DateTime value that, when present,
+ specifies the version of the blob to operate on. It's for service version 2019-10-10 and newer.
+ :type version_id: str
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param tags: Blob tags.
+ :type tags: ~azure.storage.blob.models.BlobTags
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_tags = None
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_tags = modified_access_conditions.if_tags
+ comp = "tags"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_tags.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if version_id is not None:
+ query_parameters['versionid'] = self._serialize.query("version_id", version_id, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ if tags is not None:
+ body_content = self._serialize.body(tags, 'BlobTags', is_xml=True)
+ else:
+ body_content = None
+ body_content_kwargs['content'] = body_content
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [204]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_tags.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_block_blob_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_block_blob_operations.py
new file mode 100644
index 00000000000..3cbe55e0be5
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_block_blob_operations.py
@@ -0,0 +1,1148 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import TYPE_CHECKING
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import HttpRequest, HttpResponse
+
+from .. import models as _models
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import,ungrouped-imports
+ from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union
+
+ T = TypeVar('T')
+ ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
+
+class BlockBlobOperations(object):
+ """BlockBlobOperations operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer):
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ def upload(
+ self,
+ content_length, # type: int
+ body, # type: IO
+ timeout=None, # type: Optional[int]
+ transactional_content_md5=None, # type: Optional[bytearray]
+ metadata=None, # type: Optional[str]
+ tier=None, # type: Optional[Union[str, "_models.AccessTierOptional"]]
+ request_id_parameter=None, # type: Optional[str]
+ blob_tags_string=None, # type: Optional[str]
+ immutability_policy_expiry=None, # type: Optional[datetime.datetime]
+ immutability_policy_mode=None, # type: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]]
+ legal_hold=None, # type: Optional[bool]
+ blob_http_headers=None, # type: Optional["_models.BlobHTTPHeaders"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Upload Block Blob operation updates the content of an existing block blob. Updating an
+ existing block blob overwrites any existing metadata on the blob. Partial updates are not
+ supported with Put Blob; the content of the existing blob is overwritten with the content of
+ the new blob. To perform a partial update of the content of a block blob, use the Put Block
+ List operation.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param body: Initial data.
+ :type body: IO
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _blob_cache_control = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if blob_http_headers is not None:
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ blob_type = "BlockBlob"
+ content_type = kwargs.pop("content_type", "application/octet-stream")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.upload.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content_kwargs['stream_content'] = body
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ upload.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def put_blob_from_url(
+ self,
+ content_length, # type: int
+ copy_source, # type: str
+ timeout=None, # type: Optional[int]
+ transactional_content_md5=None, # type: Optional[bytearray]
+ metadata=None, # type: Optional[str]
+ tier=None, # type: Optional[Union[str, "_models.AccessTierOptional"]]
+ request_id_parameter=None, # type: Optional[str]
+ source_content_md5=None, # type: Optional[bytearray]
+ blob_tags_string=None, # type: Optional[str]
+ copy_source_blob_properties=None, # type: Optional[bool]
+ copy_source_authorization=None, # type: Optional[str]
+ blob_http_headers=None, # type: Optional["_models.BlobHTTPHeaders"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ source_modified_access_conditions=None, # type: Optional["_models.SourceModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Put Blob from URL operation creates a new Block Blob where the contents of the blob are
+ read from a given URL. This API is supported beginning with the 2020-04-08 version. Partial
+ updates are not supported with Put Blob from URL; the content of an existing blob is
+ overwritten with the content of the new blob. To perform partial updates to a block blob’s
+ contents using a source URL, use the Put Block from URL API in conjunction with Put Block List.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
+ up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
+ would appear in a request URI. The source blob must either be public or must be authenticated
+ via a shared access signature.
+ :type copy_source: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param copy_source_blob_properties: Optional, default is true. Indicates if properties from
+ the source blob should be copied.
+ :type copy_source_blob_properties: bool
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _blob_cache_control = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ _source_if_tags = None
+ if blob_http_headers is not None:
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ _source_if_tags = source_modified_access_conditions.source_if_tags
+ blob_type = "BlockBlob"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.put_blob_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ if _source_if_tags is not None:
+ header_parameters['x-ms-source-if-tags'] = self._serialize.header("source_if_tags", _source_if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
+ if copy_source_blob_properties is not None:
+ header_parameters['x-ms-copy-source-blob-properties'] = self._serialize.header("copy_source_blob_properties", copy_source_blob_properties, 'bool')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ put_blob_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def stage_block(
+ self,
+ block_id, # type: str
+ content_length, # type: int
+ body, # type: IO
+ transactional_content_md5=None, # type: Optional[bytearray]
+ transactional_content_crc64=None, # type: Optional[bytearray]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Stage Block operation creates a new block to be committed as part of a blob.
+
+ :param block_id: A valid Base64 string value that identifies the block. Prior to encoding, the
+ string must be less than or equal to 64 bytes in size. For a given blob, the length of the
+ value specified for the blockid parameter must be the same size for each block.
+ :type block_id: str
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param body: Initial data.
+ :type body: IO
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ comp = "block"
+ content_type = kwargs.pop("content_type", "application/octet-stream")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.stage_block.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['blockid'] = self._serialize.query("block_id", block_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content_kwargs['stream_content'] = body
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ stage_block.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def stage_block_from_url(
+ self,
+ block_id, # type: str
+ content_length, # type: int
+ source_url, # type: str
+ source_range=None, # type: Optional[str]
+ source_content_md5=None, # type: Optional[bytearray]
+ source_contentcrc64=None, # type: Optional[bytearray]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ copy_source_authorization=None, # type: Optional[str]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ source_modified_access_conditions=None, # type: Optional["_models.SourceModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Stage Block operation creates a new block to be committed as part of a blob where the
+ contents are read from a URL.
+
+ :param block_id: A valid Base64 string value that identifies the block. Prior to encoding, the
+ string must be less than or equal to 64 bytes in size. For a given blob, the length of the
+ value specified for the blockid parameter must be the same size for each block.
+ :type block_id: str
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param source_url: Specify a URL to the copy source.
+ :type source_url: str
+ :param source_range: Bytes of source data in the specified range.
+ :type source_range: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param source_contentcrc64: Specify the crc64 calculated for the range of bytes that must be
+ read from the copy source.
+ :type source_contentcrc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _lease_id = None
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ comp = "block"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.stage_block_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['blockid'] = self._serialize.query("block_id", block_id, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("source_url", source_url, 'str')
+ if source_range is not None:
+ header_parameters['x-ms-source-range'] = self._serialize.header("source_range", source_range, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if source_contentcrc64 is not None:
+ header_parameters['x-ms-source-content-crc64'] = self._serialize.header("source_contentcrc64", source_contentcrc64, 'bytearray')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ stage_block_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def commit_block_list(
+ self,
+ blocks, # type: "_models.BlockLookupList"
+ timeout=None, # type: Optional[int]
+ transactional_content_md5=None, # type: Optional[bytearray]
+ transactional_content_crc64=None, # type: Optional[bytearray]
+ metadata=None, # type: Optional[str]
+ tier=None, # type: Optional[Union[str, "_models.AccessTierOptional"]]
+ request_id_parameter=None, # type: Optional[str]
+ blob_tags_string=None, # type: Optional[str]
+ immutability_policy_expiry=None, # type: Optional[datetime.datetime]
+ immutability_policy_mode=None, # type: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]]
+ legal_hold=None, # type: Optional[bool]
+ blob_http_headers=None, # type: Optional["_models.BlobHTTPHeaders"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Commit Block List operation writes a blob by specifying the list of block IDs that make up
+ the blob. In order to be written as part of a blob, a block must have been successfully written
+ to the server in a prior Put Block operation. You can call Put Block List to update a blob by
+ uploading only those blocks that have changed, then committing the new and existing blocks
+ together. You can do this by specifying whether to commit a block from the committed block list
+ or from the uncommitted block list, or to commit the most recently uploaded version of the
+ block, whichever list it may belong to.
+
+ :param blocks: Blob Blocks.
+ :type blocks: ~azure.storage.blob.models.BlockLookupList
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param tier: Optional. Indicates the tier to be set on the blob.
+ :type tier: str or ~azure.storage.blob.models.AccessTierOptional
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_cache_control = None
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if blob_http_headers is not None:
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "blocklist"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.commit_block_list.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(blocks, 'BlockLookupList', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ commit_block_list.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def get_block_list(
+ self,
+ snapshot=None, # type: Optional[str]
+ list_type="committed", # type: Union[str, "_models.BlockListType"]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.BlockList"
+ """The Get Block List operation retrieves the list of blocks that have been uploaded as part of a
+ block blob.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param list_type: Specifies whether to return the list of committed blocks, the list of
+ uncommitted blocks, or both lists together.
+ :type list_type: str or ~azure.storage.blob.models.BlockListType
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: BlockList, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.BlockList
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.BlockList"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_tags = modified_access_conditions.if_tags
+ comp = "blocklist"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_block_list.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ query_parameters['blocklisttype'] = self._serialize.query("list_type", list_type, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-blob-content-length']=self._deserialize('long', response.headers.get('x-ms-blob-content-length'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('BlockList', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_block_list.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_container_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_container_operations.py
new file mode 100644
index 00000000000..c9f8080eebf
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_container_operations.py
@@ -0,0 +1,1770 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import TYPE_CHECKING
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import HttpRequest, HttpResponse
+
+from .. import models as _models
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import,ungrouped-imports
+ from typing import Any, Callable, Dict, Generic, IO, List, Optional, TypeVar, Union
+
+ T = TypeVar('T')
+ ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
+
+class ContainerOperations(object):
+ """ContainerOperations operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer):
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ def create(
+ self,
+ timeout=None, # type: Optional[int]
+ metadata=None, # type: Optional[str]
+ access=None, # type: Optional[Union[str, "_models.PublicAccessType"]]
+ request_id_parameter=None, # type: Optional[str]
+ container_cpk_scope_info=None, # type: Optional["_models.ContainerCpkScopeInfo"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """creates a new container under the specified account. If the container with the same name
+ already exists, the operation fails.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param access: Specifies whether data in the container may be accessed publicly and the level
+ of access.
+ :type access: str or ~azure.storage.blob.models.PublicAccessType
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param container_cpk_scope_info: Parameter group.
+ :type container_cpk_scope_info: ~azure.storage.blob.models.ContainerCpkScopeInfo
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _default_encryption_scope = None
+ _prevent_encryption_scope_override = None
+ if container_cpk_scope_info is not None:
+ _default_encryption_scope = container_cpk_scope_info.default_encryption_scope
+ _prevent_encryption_scope_override = container_cpk_scope_info.prevent_encryption_scope_override
+ restype = "container"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.create.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if access is not None:
+ header_parameters['x-ms-blob-public-access'] = self._serialize.header("access", access, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if _default_encryption_scope is not None:
+ header_parameters['x-ms-default-encryption-scope'] = self._serialize.header("default_encryption_scope", _default_encryption_scope, 'str')
+ if _prevent_encryption_scope_override is not None:
+ header_parameters['x-ms-deny-encryption-scope-override'] = self._serialize.header("prevent_encryption_scope_override", _prevent_encryption_scope_override, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ create.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def get_properties(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """returns all user-defined metadata and system properties for the specified container. The data
+ returned does not include the container's list of blobs.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ restype = "container"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_properties.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-meta']=self._deserialize('str', response.headers.get('x-ms-meta'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-duration']=self._deserialize('str', response.headers.get('x-ms-lease-duration'))
+ response_headers['x-ms-lease-state']=self._deserialize('str', response.headers.get('x-ms-lease-state'))
+ response_headers['x-ms-lease-status']=self._deserialize('str', response.headers.get('x-ms-lease-status'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-blob-public-access']=self._deserialize('str', response.headers.get('x-ms-blob-public-access'))
+ response_headers['x-ms-has-immutability-policy']=self._deserialize('bool', response.headers.get('x-ms-has-immutability-policy'))
+ response_headers['x-ms-has-legal-hold']=self._deserialize('bool', response.headers.get('x-ms-has-legal-hold'))
+ response_headers['x-ms-default-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-default-encryption-scope'))
+ response_headers['x-ms-deny-encryption-scope-override']=self._deserialize('bool', response.headers.get('x-ms-deny-encryption-scope-override'))
+ response_headers['x-ms-immutable-storage-with-versioning-enabled']=self._deserialize('bool', response.headers.get('x-ms-immutable-storage-with-versioning-enabled'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_properties.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def delete(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """operation marks the specified container for deletion. The container and any blobs contained
+ within it are later deleted during garbage collection.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ restype = "container"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.delete.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.delete(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ delete.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def set_metadata(
+ self,
+ timeout=None, # type: Optional[int]
+ metadata=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """operation sets one or more user-defined name-value pairs for the specified container.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ restype = "container"
+ comp = "metadata"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_metadata.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_metadata.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def get_access_policy(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> List["_models.SignedIdentifier"]
+ """gets the permissions for the specified container. The permissions indicate whether container
+ data may be accessed publicly.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: list of SignedIdentifier, or the result of cls(response)
+ :rtype: list[~azure.storage.blob.models.SignedIdentifier]
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[List["_models.SignedIdentifier"]]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ restype = "container"
+ comp = "acl"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_access_policy.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-blob-public-access']=self._deserialize('str', response.headers.get('x-ms-blob-public-access'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('[SignedIdentifier]', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_access_policy.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def set_access_policy(
+ self,
+ timeout=None, # type: Optional[int]
+ access=None, # type: Optional[Union[str, "_models.PublicAccessType"]]
+ request_id_parameter=None, # type: Optional[str]
+ container_acl=None, # type: Optional[List["_models.SignedIdentifier"]]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """sets the permissions for the specified container. The permissions indicate whether blobs in a
+ container may be accessed publicly.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param access: Specifies whether data in the container may be accessed publicly and the level
+ of access.
+ :type access: str or ~azure.storage.blob.models.PublicAccessType
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param container_acl: the acls for the container.
+ :type container_acl: list[~azure.storage.blob.models.SignedIdentifier]
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ restype = "container"
+ comp = "acl"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_access_policy.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if access is not None:
+ header_parameters['x-ms-blob-public-access'] = self._serialize.header("access", access, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ serialization_ctxt = {'xml': {'name': 'SignedIdentifiers', 'wrapped': True, 'itemsName': 'SignedIdentifier'}}
+ if container_acl is not None:
+ body_content = self._serialize.body(container_acl, '[SignedIdentifier]', is_xml=True, serialization_ctxt=serialization_ctxt)
+ else:
+ body_content = None
+ body_content_kwargs['content'] = body_content
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_access_policy.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def restore(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ deleted_container_name=None, # type: Optional[str]
+ deleted_container_version=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Restores a previously-deleted container.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param deleted_container_name: Optional. Version 2019-12-12 and later. Specifies the name of
+ the deleted container to restore.
+ :type deleted_container_name: str
+ :param deleted_container_version: Optional. Version 2019-12-12 and later. Specifies the
+ version of the deleted container to restore.
+ :type deleted_container_version: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "undelete"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.restore.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if deleted_container_name is not None:
+ header_parameters['x-ms-deleted-container-name'] = self._serialize.header("deleted_container_name", deleted_container_name, 'str')
+ if deleted_container_version is not None:
+ header_parameters['x-ms-deleted-container-version'] = self._serialize.header("deleted_container_version", deleted_container_version, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ restore.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def rename(
+ self,
+ source_container_name, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ source_lease_id=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Renames an existing container.
+
+ :param source_container_name: Required. Specifies the name of the container to rename.
+ :type source_container_name: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param source_lease_id: A lease ID for the source path. If specified, the source path must have
+ an active lease and the lease ID must match.
+ :type source_lease_id: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "rename"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.rename.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['x-ms-source-container-name'] = self._serialize.header("source_container_name", source_container_name, 'str')
+ if source_lease_id is not None:
+ header_parameters['x-ms-source-lease-id'] = self._serialize.header("source_lease_id", source_lease_id, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ rename.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def submit_batch(
+ self,
+ content_length, # type: int
+ multipart_content_type, # type: str
+ body, # type: IO
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> IO
+ """The Batch operation allows multiple API calls to be embedded into a single HTTP request.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param multipart_content_type: Required. The value of this header must be multipart/mixed with
+ a batch boundary. Example header value: multipart/mixed; boundary=batch_:code:``.
+ :type multipart_content_type: str
+ :param body: Initial data.
+ :type body: IO
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: IO, or the result of cls(response)
+ :rtype: IO
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[IO]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "batch"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.submit_batch.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ header_parameters['Content-Type'] = self._serialize.header("multipart_content_type", multipart_content_type, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(body, 'IO', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=True, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ submit_batch.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def filter_blobs(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ where=None, # type: Optional[str]
+ marker=None, # type: Optional[str]
+ maxresults=None, # type: Optional[int]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.FilterBlobSegment"
+ """The Filter Blobs operation enables callers to list blobs in a container whose tags match a
+ given search expression. Filter blobs searches within the given container.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param where: Filters the results to return only to return only blobs whose tags match the
+ specified expression.
+ :type where: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: FilterBlobSegment, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.FilterBlobSegment
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.FilterBlobSegment"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "blobs"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.filter_blobs.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if where is not None:
+ query_parameters['where'] = self._serialize.query("where", where, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('FilterBlobSegment', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ filter_blobs.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def acquire_lease(
+ self,
+ timeout=None, # type: Optional[int]
+ duration=None, # type: Optional[int]
+ proposed_lease_id=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param duration: Specifies the duration of the lease, in seconds, or negative one (-1) for a
+ lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease
+ duration cannot be changed using renew or change.
+ :type duration: int
+ :param proposed_lease_id: Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid
+ Constructor (String) for a list of valid GUID string formats.
+ :type proposed_lease_id: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "acquire"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.acquire_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ if duration is not None:
+ header_parameters['x-ms-lease-duration'] = self._serialize.header("duration", duration, 'int')
+ if proposed_lease_id is not None:
+ header_parameters['x-ms-proposed-lease-id'] = self._serialize.header("proposed_lease_id", proposed_lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ acquire_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def release_lease(
+ self,
+ lease_id, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "release"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.release_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ release_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def renew_lease(
+ self,
+ lease_id, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "renew"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.renew_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ renew_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def break_lease(
+ self,
+ timeout=None, # type: Optional[int]
+ break_period=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param break_period: For a break operation, proposed duration the lease should continue before
+ it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter
+ than the time remaining on the lease. If longer, the time remaining on the lease is used. A new
+ lease will not be available before the break period has expired, but the lease may be held for
+ longer than the break period. If this header does not appear with a break operation, a
+ fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease
+ breaks immediately.
+ :type break_period: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "break"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.break_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ if break_period is not None:
+ header_parameters['x-ms-lease-break-period'] = self._serialize.header("break_period", break_period, 'int')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-time']=self._deserialize('int', response.headers.get('x-ms-lease-time'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ break_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def change_lease(
+ self,
+ lease_id, # type: str
+ proposed_lease_id, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """[Update] establishes and manages a lock on a container for delete operations. The lock duration
+ can be 15 to 60 seconds, or can be infinite.
+
+ :param lease_id: Specifies the current lease ID on the resource.
+ :type lease_id: str
+ :param proposed_lease_id: Proposed lease ID, in a GUID string format. The Blob service returns
+ 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid
+ Constructor (String) for a list of valid GUID string formats.
+ :type proposed_lease_id: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ comp = "lease"
+ restype = "container"
+ action = "change"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.change_lease.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-lease-action'] = self._serialize.header("action", action, 'str')
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", lease_id, 'str')
+ header_parameters['x-ms-proposed-lease-id'] = self._serialize.header("proposed_lease_id", proposed_lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-lease-id']=self._deserialize('str', response.headers.get('x-ms-lease-id'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ change_lease.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def list_blob_flat_segment(
+ self,
+ prefix=None, # type: Optional[str]
+ marker=None, # type: Optional[str]
+ maxresults=None, # type: Optional[int]
+ include=None, # type: Optional[List[Union[str, "_models.ListBlobsIncludeItem"]]]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.ListBlobsFlatSegmentResponse"
+ """[Update] The List Blobs operation returns a list of the blobs under the specified container.
+
+ :param prefix: Filters the results to return only containers whose name begins with the
+ specified prefix.
+ :type prefix: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :param include: Include this parameter to specify one or more datasets to include in the
+ response.
+ :type include: list[str or ~azure.storage.blob.models.ListBlobsIncludeItem]
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: ListBlobsFlatSegmentResponse, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.ListBlobsFlatSegmentResponse
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.ListBlobsFlatSegmentResponse"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "list"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.list_blob_flat_segment.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if prefix is not None:
+ query_parameters['prefix'] = self._serialize.query("prefix", prefix, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+ if include is not None:
+ query_parameters['include'] = self._serialize.query("include", include, '[str]', div=',')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('ListBlobsFlatSegmentResponse', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ list_blob_flat_segment.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def list_blob_hierarchy_segment(
+ self,
+ delimiter, # type: str
+ prefix=None, # type: Optional[str]
+ marker=None, # type: Optional[str]
+ maxresults=None, # type: Optional[int]
+ include=None, # type: Optional[List[Union[str, "_models.ListBlobsIncludeItem"]]]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.ListBlobsHierarchySegmentResponse"
+ """[Update] The List Blobs operation returns a list of the blobs under the specified container.
+
+ :param delimiter: When the request includes this parameter, the operation returns a BlobPrefix
+ element in the response body that acts as a placeholder for all blobs whose names begin with
+ the same substring up to the appearance of the delimiter character. The delimiter may be a
+ single character or a string.
+ :type delimiter: str
+ :param prefix: Filters the results to return only containers whose name begins with the
+ specified prefix.
+ :type prefix: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :param include: Include this parameter to specify one or more datasets to include in the
+ response.
+ :type include: list[str or ~azure.storage.blob.models.ListBlobsIncludeItem]
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: ListBlobsHierarchySegmentResponse, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.ListBlobsHierarchySegmentResponse
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.ListBlobsHierarchySegmentResponse"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "container"
+ comp = "list"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.list_blob_hierarchy_segment.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if prefix is not None:
+ query_parameters['prefix'] = self._serialize.query("prefix", prefix, 'str')
+ query_parameters['delimiter'] = self._serialize.query("delimiter", delimiter, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+ if include is not None:
+ query_parameters['include'] = self._serialize.query("include", include, '[str]', div=',')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('ListBlobsHierarchySegmentResponse', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ list_blob_hierarchy_segment.metadata = {'url': '/{containerName}'} # type: ignore
+
+ def get_account_info(
+ self,
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Returns the sku name and account kind.
+
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "account"
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_account_info.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-sku-name']=self._deserialize('str', response.headers.get('x-ms-sku-name'))
+ response_headers['x-ms-account-kind']=self._deserialize('str', response.headers.get('x-ms-account-kind'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_account_info.metadata = {'url': '/{containerName}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_page_blob_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_page_blob_operations.py
new file mode 100644
index 00000000000..c953df2b9a7
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_page_blob_operations.py
@@ -0,0 +1,1437 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+import datetime
+from typing import TYPE_CHECKING
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import HttpRequest, HttpResponse
+
+from .. import models as _models
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import,ungrouped-imports
+ from typing import Any, Callable, Dict, Generic, IO, Optional, TypeVar, Union
+
+ T = TypeVar('T')
+ ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
+
+class PageBlobOperations(object):
+ """PageBlobOperations operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer):
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ def create(
+ self,
+ content_length, # type: int
+ blob_content_length, # type: int
+ timeout=None, # type: Optional[int]
+ tier=None, # type: Optional[Union[str, "_models.PremiumPageBlobAccessTier"]]
+ metadata=None, # type: Optional[str]
+ blob_sequence_number=0, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ blob_tags_string=None, # type: Optional[str]
+ immutability_policy_expiry=None, # type: Optional[datetime.datetime]
+ immutability_policy_mode=None, # type: Optional[Union[str, "_models.BlobImmutabilityPolicyMode"]]
+ legal_hold=None, # type: Optional[bool]
+ blob_http_headers=None, # type: Optional["_models.BlobHTTPHeaders"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Create operation creates a new page blob.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param blob_content_length: This header specifies the maximum size for the page blob, up to 1
+ TB. The page blob size must be aligned to a 512-byte boundary.
+ :type blob_content_length: long
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param tier: Optional. Indicates the tier to be set on the page blob.
+ :type tier: str or ~azure.storage.blob.models.PremiumPageBlobAccessTier
+ :param metadata: Optional. Specifies a user-defined name-value pair associated with the blob.
+ If no name-value pairs are specified, the operation will copy the metadata from the source blob
+ or file to the destination blob. If one or more name-value pairs are specified, the destination
+ blob is created with the specified metadata, and metadata is not copied from the source blob or
+ file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming
+ rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more
+ information.
+ :type metadata: str
+ :param blob_sequence_number: Set for page blobs only. The sequence number is a user-controlled
+ value that you can use to track requests. The value of the sequence number must be between 0
+ and 2^63 - 1.
+ :type blob_sequence_number: long
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param blob_tags_string: Optional. Used to set blob tags in various blob operations.
+ :type blob_tags_string: str
+ :param immutability_policy_expiry: Specifies the date time when the blobs immutability policy
+ is set to expire.
+ :type immutability_policy_expiry: ~datetime.datetime
+ :param immutability_policy_mode: Specifies the immutability policy mode to set on the blob.
+ :type immutability_policy_mode: str or ~azure.storage.blob.models.BlobImmutabilityPolicyMode
+ :param legal_hold: Specified if a legal hold should be set on the blob.
+ :type legal_hold: bool
+ :param blob_http_headers: Parameter group.
+ :type blob_http_headers: ~azure.storage.blob.models.BlobHTTPHeaders
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _blob_content_type = None
+ _blob_content_encoding = None
+ _blob_content_language = None
+ _blob_content_md5 = None
+ _blob_cache_control = None
+ _lease_id = None
+ _blob_content_disposition = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if blob_http_headers is not None:
+ _blob_content_type = blob_http_headers.blob_content_type
+ _blob_content_encoding = blob_http_headers.blob_content_encoding
+ _blob_content_language = blob_http_headers.blob_content_language
+ _blob_content_md5 = blob_http_headers.blob_content_md5
+ _blob_cache_control = blob_http_headers.blob_cache_control
+ _blob_content_disposition = blob_http_headers.blob_content_disposition
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ blob_type = "PageBlob"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.create.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-blob-type'] = self._serialize.header("blob_type", blob_type, 'str')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if tier is not None:
+ header_parameters['x-ms-access-tier'] = self._serialize.header("tier", tier, 'str')
+ if _blob_content_type is not None:
+ header_parameters['x-ms-blob-content-type'] = self._serialize.header("blob_content_type", _blob_content_type, 'str')
+ if _blob_content_encoding is not None:
+ header_parameters['x-ms-blob-content-encoding'] = self._serialize.header("blob_content_encoding", _blob_content_encoding, 'str')
+ if _blob_content_language is not None:
+ header_parameters['x-ms-blob-content-language'] = self._serialize.header("blob_content_language", _blob_content_language, 'str')
+ if _blob_content_md5 is not None:
+ header_parameters['x-ms-blob-content-md5'] = self._serialize.header("blob_content_md5", _blob_content_md5, 'bytearray')
+ if _blob_cache_control is not None:
+ header_parameters['x-ms-blob-cache-control'] = self._serialize.header("blob_cache_control", _blob_cache_control, 'str')
+ if metadata is not None:
+ header_parameters['x-ms-meta'] = self._serialize.header("metadata", metadata, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _blob_content_disposition is not None:
+ header_parameters['x-ms-blob-content-disposition'] = self._serialize.header("blob_content_disposition", _blob_content_disposition, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-blob-content-length'] = self._serialize.header("blob_content_length", blob_content_length, 'long')
+ if blob_sequence_number is not None:
+ header_parameters['x-ms-blob-sequence-number'] = self._serialize.header("blob_sequence_number", blob_sequence_number, 'long')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if blob_tags_string is not None:
+ header_parameters['x-ms-tags'] = self._serialize.header("blob_tags_string", blob_tags_string, 'str')
+ if immutability_policy_expiry is not None:
+ header_parameters['x-ms-immutability-policy-until-date'] = self._serialize.header("immutability_policy_expiry", immutability_policy_expiry, 'rfc-1123')
+ if immutability_policy_mode is not None:
+ header_parameters['x-ms-immutability-policy-mode'] = self._serialize.header("immutability_policy_mode", immutability_policy_mode, 'str')
+ if legal_hold is not None:
+ header_parameters['x-ms-legal-hold'] = self._serialize.header("legal_hold", legal_hold, 'bool')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['x-ms-version-id']=self._deserialize('str', response.headers.get('x-ms-version-id'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ create.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def upload_pages(
+ self,
+ content_length, # type: int
+ body, # type: IO
+ transactional_content_md5=None, # type: Optional[bytearray]
+ transactional_content_crc64=None, # type: Optional[bytearray]
+ timeout=None, # type: Optional[int]
+ range=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ sequence_number_access_conditions=None, # type: Optional["_models.SequenceNumberAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Upload Pages operation writes a range of pages to a page blob.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param body: Initial data.
+ :type body: IO
+ :param transactional_content_md5: Specify the transactional md5 for the body, to be validated
+ by the service.
+ :type transactional_content_md5: bytearray
+ :param transactional_content_crc64: Specify the transactional crc64 for the body, to be
+ validated by the service.
+ :type transactional_content_crc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param sequence_number_access_conditions: Parameter group.
+ :type sequence_number_access_conditions: ~azure.storage.blob.models.SequenceNumberAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_sequence_number_less_than_or_equal_to = None
+ _if_sequence_number_less_than = None
+ _if_sequence_number_equal_to = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if sequence_number_access_conditions is not None:
+ _if_sequence_number_less_than_or_equal_to = sequence_number_access_conditions.if_sequence_number_less_than_or_equal_to
+ _if_sequence_number_less_than = sequence_number_access_conditions.if_sequence_number_less_than
+ _if_sequence_number_equal_to = sequence_number_access_conditions.if_sequence_number_equal_to
+ comp = "page"
+ page_write = "update"
+ content_type = kwargs.pop("content_type", "application/octet-stream")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.upload_pages.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-page-write'] = self._serialize.header("page_write", page_write, 'str')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if transactional_content_md5 is not None:
+ header_parameters['Content-MD5'] = self._serialize.header("transactional_content_md5", transactional_content_md5, 'bytearray')
+ if transactional_content_crc64 is not None:
+ header_parameters['x-ms-content-crc64'] = self._serialize.header("transactional_content_crc64", transactional_content_crc64, 'bytearray')
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_sequence_number_less_than_or_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-le'] = self._serialize.header("if_sequence_number_less_than_or_equal_to", _if_sequence_number_less_than_or_equal_to, 'long')
+ if _if_sequence_number_less_than is not None:
+ header_parameters['x-ms-if-sequence-number-lt'] = self._serialize.header("if_sequence_number_less_than", _if_sequence_number_less_than, 'long')
+ if _if_sequence_number_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-eq'] = self._serialize.header("if_sequence_number_equal_to", _if_sequence_number_equal_to, 'long')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content_kwargs['stream_content'] = body
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ upload_pages.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def clear_pages(
+ self,
+ content_length, # type: int
+ timeout=None, # type: Optional[int]
+ range=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ sequence_number_access_conditions=None, # type: Optional["_models.SequenceNumberAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Clear Pages operation clears a set of pages from a page blob.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param sequence_number_access_conditions: Parameter group.
+ :type sequence_number_access_conditions: ~azure.storage.blob.models.SequenceNumberAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_sequence_number_less_than_or_equal_to = None
+ _if_sequence_number_less_than = None
+ _if_sequence_number_equal_to = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if sequence_number_access_conditions is not None:
+ _if_sequence_number_less_than_or_equal_to = sequence_number_access_conditions.if_sequence_number_less_than_or_equal_to
+ _if_sequence_number_less_than = sequence_number_access_conditions.if_sequence_number_less_than
+ _if_sequence_number_equal_to = sequence_number_access_conditions.if_sequence_number_equal_to
+ comp = "page"
+ page_write = "clear"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.clear_pages.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-page-write'] = self._serialize.header("page_write", page_write, 'str')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_sequence_number_less_than_or_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-le'] = self._serialize.header("if_sequence_number_less_than_or_equal_to", _if_sequence_number_less_than_or_equal_to, 'long')
+ if _if_sequence_number_less_than is not None:
+ header_parameters['x-ms-if-sequence-number-lt'] = self._serialize.header("if_sequence_number_less_than", _if_sequence_number_less_than, 'long')
+ if _if_sequence_number_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-eq'] = self._serialize.header("if_sequence_number_equal_to", _if_sequence_number_equal_to, 'long')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ clear_pages.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def upload_pages_from_url(
+ self,
+ source_url, # type: str
+ source_range, # type: str
+ content_length, # type: int
+ range, # type: str
+ source_content_md5=None, # type: Optional[bytearray]
+ source_contentcrc64=None, # type: Optional[bytearray]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ copy_source_authorization=None, # type: Optional[str]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ sequence_number_access_conditions=None, # type: Optional["_models.SequenceNumberAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ source_modified_access_conditions=None, # type: Optional["_models.SourceModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Upload Pages operation writes a range of pages to a page blob where the contents are read
+ from a URL.
+
+ :param source_url: Specify a URL to the copy source.
+ :type source_url: str
+ :param source_range: Bytes of source data in the specified range. The length of this range
+ should match the ContentLength header and x-ms-range/Range destination range header.
+ :type source_range: str
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param range: The range of bytes to which the source range would be written. The range should
+ be 512 aligned and range-end is required.
+ :type range: str
+ :param source_content_md5: Specify the md5 calculated for the range of bytes that must be read
+ from the copy source.
+ :type source_content_md5: bytearray
+ :param source_contentcrc64: Specify the crc64 calculated for the range of bytes that must be
+ read from the copy source.
+ :type source_contentcrc64: bytearray
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param copy_source_authorization: Only Bearer type is supported. Credentials should be a valid
+ OAuth access token to copy source.
+ :type copy_source_authorization: str
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param sequence_number_access_conditions: Parameter group.
+ :type sequence_number_access_conditions: ~azure.storage.blob.models.SequenceNumberAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :param source_modified_access_conditions: Parameter group.
+ :type source_modified_access_conditions: ~azure.storage.blob.models.SourceModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _lease_id = None
+ _if_sequence_number_less_than_or_equal_to = None
+ _if_sequence_number_less_than = None
+ _if_sequence_number_equal_to = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ _source_if_modified_since = None
+ _source_if_unmodified_since = None
+ _source_if_match = None
+ _source_if_none_match = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ if sequence_number_access_conditions is not None:
+ _if_sequence_number_less_than_or_equal_to = sequence_number_access_conditions.if_sequence_number_less_than_or_equal_to
+ _if_sequence_number_less_than = sequence_number_access_conditions.if_sequence_number_less_than
+ _if_sequence_number_equal_to = sequence_number_access_conditions.if_sequence_number_equal_to
+ if source_modified_access_conditions is not None:
+ _source_if_modified_since = source_modified_access_conditions.source_if_modified_since
+ _source_if_unmodified_since = source_modified_access_conditions.source_if_unmodified_since
+ _source_if_match = source_modified_access_conditions.source_if_match
+ _source_if_none_match = source_modified_access_conditions.source_if_none_match
+ comp = "page"
+ page_write = "update"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.upload_pages_from_url.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-page-write'] = self._serialize.header("page_write", page_write, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("source_url", source_url, 'str')
+ header_parameters['x-ms-source-range'] = self._serialize.header("source_range", source_range, 'str')
+ if source_content_md5 is not None:
+ header_parameters['x-ms-source-content-md5'] = self._serialize.header("source_content_md5", source_content_md5, 'bytearray')
+ if source_contentcrc64 is not None:
+ header_parameters['x-ms-source-content-crc64'] = self._serialize.header("source_contentcrc64", source_contentcrc64, 'bytearray')
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_sequence_number_less_than_or_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-le'] = self._serialize.header("if_sequence_number_less_than_or_equal_to", _if_sequence_number_less_than_or_equal_to, 'long')
+ if _if_sequence_number_less_than is not None:
+ header_parameters['x-ms-if-sequence-number-lt'] = self._serialize.header("if_sequence_number_less_than", _if_sequence_number_less_than, 'long')
+ if _if_sequence_number_equal_to is not None:
+ header_parameters['x-ms-if-sequence-number-eq'] = self._serialize.header("if_sequence_number_equal_to", _if_sequence_number_equal_to, 'long')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ if _source_if_modified_since is not None:
+ header_parameters['x-ms-source-if-modified-since'] = self._serialize.header("source_if_modified_since", _source_if_modified_since, 'rfc-1123')
+ if _source_if_unmodified_since is not None:
+ header_parameters['x-ms-source-if-unmodified-since'] = self._serialize.header("source_if_unmodified_since", _source_if_unmodified_since, 'rfc-1123')
+ if _source_if_match is not None:
+ header_parameters['x-ms-source-if-match'] = self._serialize.header("source_if_match", _source_if_match, 'str')
+ if _source_if_none_match is not None:
+ header_parameters['x-ms-source-if-none-match'] = self._serialize.header("source_if_none_match", _source_if_none_match, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ if copy_source_authorization is not None:
+ header_parameters['x-ms-copy-source-authorization'] = self._serialize.header("copy_source_authorization", copy_source_authorization, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [201]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['Content-MD5']=self._deserialize('bytearray', response.headers.get('Content-MD5'))
+ response_headers['x-ms-content-crc64']=self._deserialize('bytearray', response.headers.get('x-ms-content-crc64'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-request-server-encrypted']=self._deserialize('bool', response.headers.get('x-ms-request-server-encrypted'))
+ response_headers['x-ms-encryption-key-sha256']=self._deserialize('str', response.headers.get('x-ms-encryption-key-sha256'))
+ response_headers['x-ms-encryption-scope']=self._deserialize('str', response.headers.get('x-ms-encryption-scope'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ upload_pages_from_url.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def get_page_ranges(
+ self,
+ snapshot=None, # type: Optional[str]
+ timeout=None, # type: Optional[int]
+ range=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.PageList"
+ """The Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot
+ of a page blob.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: PageList, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.PageList
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.PageList"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "pagelist"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_page_ranges.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['x-ms-blob-content-length']=self._deserialize('long', response.headers.get('x-ms-blob-content-length'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('PageList', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_page_ranges.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def get_page_ranges_diff(
+ self,
+ snapshot=None, # type: Optional[str]
+ timeout=None, # type: Optional[int]
+ prevsnapshot=None, # type: Optional[str]
+ prev_snapshot_url=None, # type: Optional[str]
+ range=None, # type: Optional[str]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.PageList"
+ """The Get Page Ranges Diff operation returns the list of valid page ranges for a page blob that
+ were changed between target blob and previous snapshot.
+
+ :param snapshot: The snapshot parameter is an opaque DateTime value that, when present,
+ specifies the blob snapshot to retrieve. For more information on working with blob snapshots,
+ see :code:`Creating
+ a Snapshot of a Blob.`.
+ :type snapshot: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param prevsnapshot: Optional in version 2015-07-08 and newer. The prevsnapshot parameter is a
+ DateTime value that specifies that the response will contain only pages that were changed
+ between target blob and previous snapshot. Changed pages include both updated and cleared
+ pages. The target blob may be a snapshot, as long as the snapshot specified by prevsnapshot is
+ the older of the two. Note that incremental snapshots are currently supported only for blobs
+ created on or after January 1, 2016.
+ :type prevsnapshot: str
+ :param prev_snapshot_url: Optional. This header is only supported in service versions
+ 2019-04-19 and after and specifies the URL of a previous snapshot of the target blob. The
+ response will only contain pages that were changed between the target blob and its previous
+ snapshot.
+ :type prev_snapshot_url: str
+ :param range: Return only the bytes of the blob in the specified range.
+ :type range: str
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: PageList, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.PageList
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.PageList"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "pagelist"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_page_ranges_diff.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if snapshot is not None:
+ query_parameters['snapshot'] = self._serialize.query("snapshot", snapshot, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if prevsnapshot is not None:
+ query_parameters['prevsnapshot'] = self._serialize.query("prevsnapshot", prevsnapshot, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if prev_snapshot_url is not None:
+ header_parameters['x-ms-previous-snapshot-url'] = self._serialize.header("prev_snapshot_url", prev_snapshot_url, 'str')
+ if range is not None:
+ header_parameters['x-ms-range'] = self._serialize.header("range", range, 'str')
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['x-ms-blob-content-length']=self._deserialize('long', response.headers.get('x-ms-blob-content-length'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('PageList', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_page_ranges_diff.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def resize(
+ self,
+ blob_content_length, # type: int
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ cpk_info=None, # type: Optional["_models.CpkInfo"]
+ cpk_scope_info=None, # type: Optional["_models.CpkScopeInfo"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Resize the Blob.
+
+ :param blob_content_length: This header specifies the maximum size for the page blob, up to 1
+ TB. The page blob size must be aligned to a 512-byte boundary.
+ :type blob_content_length: long
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param cpk_info: Parameter group.
+ :type cpk_info: ~azure.storage.blob.models.CpkInfo
+ :param cpk_scope_info: Parameter group.
+ :type cpk_scope_info: ~azure.storage.blob.models.CpkScopeInfo
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _encryption_key = None
+ _encryption_key_sha256 = None
+ _encryption_algorithm = None
+ _encryption_scope = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if cpk_info is not None:
+ _encryption_key = cpk_info.encryption_key
+ _encryption_key_sha256 = cpk_info.encryption_key_sha256
+ _encryption_algorithm = cpk_info.encryption_algorithm
+ if cpk_scope_info is not None:
+ _encryption_scope = cpk_scope_info.encryption_scope
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.resize.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _encryption_key is not None:
+ header_parameters['x-ms-encryption-key'] = self._serialize.header("encryption_key", _encryption_key, 'str')
+ if _encryption_key_sha256 is not None:
+ header_parameters['x-ms-encryption-key-sha256'] = self._serialize.header("encryption_key_sha256", _encryption_key_sha256, 'str')
+ if _encryption_algorithm is not None:
+ header_parameters['x-ms-encryption-algorithm'] = self._serialize.header("encryption_algorithm", _encryption_algorithm, 'str')
+ if _encryption_scope is not None:
+ header_parameters['x-ms-encryption-scope'] = self._serialize.header("encryption_scope", _encryption_scope, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-blob-content-length'] = self._serialize.header("blob_content_length", blob_content_length, 'long')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ resize.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def update_sequence_number(
+ self,
+ sequence_number_action, # type: Union[str, "_models.SequenceNumberActionType"]
+ timeout=None, # type: Optional[int]
+ blob_sequence_number=0, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ lease_access_conditions=None, # type: Optional["_models.LeaseAccessConditions"]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Update the sequence number of the blob.
+
+ :param sequence_number_action: Required if the x-ms-blob-sequence-number header is set for the
+ request. This property applies to page blobs only. This property indicates how the service
+ should modify the blob's sequence number.
+ :type sequence_number_action: str or ~azure.storage.blob.models.SequenceNumberActionType
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param blob_sequence_number: Set for page blobs only. The sequence number is a user-controlled
+ value that you can use to track requests. The value of the sequence number must be between 0
+ and 2^63 - 1.
+ :type blob_sequence_number: long
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param lease_access_conditions: Parameter group.
+ :type lease_access_conditions: ~azure.storage.blob.models.LeaseAccessConditions
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _lease_id = None
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if lease_access_conditions is not None:
+ _lease_id = lease_access_conditions.lease_id
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.update_sequence_number.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _lease_id is not None:
+ header_parameters['x-ms-lease-id'] = self._serialize.header("lease_id", _lease_id, 'str')
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-sequence-number-action'] = self._serialize.header("sequence_number_action", sequence_number_action, 'str')
+ if blob_sequence_number is not None:
+ header_parameters['x-ms-blob-sequence-number'] = self._serialize.header("blob_sequence_number", blob_sequence_number, 'long')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-blob-sequence-number']=self._deserialize('long', response.headers.get('x-ms-blob-sequence-number'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ update_sequence_number.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
+
+ def copy_incremental(
+ self,
+ copy_source, # type: str
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ modified_access_conditions=None, # type: Optional["_models.ModifiedAccessConditions"]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """The Copy Incremental operation copies a snapshot of the source page blob to a destination page
+ blob. The snapshot is copied such that only the differential changes between the previously
+ copied snapshot are transferred to the destination. The copied snapshots are complete copies of
+ the original snapshot and can be read or copied from as usual. This API is supported since REST
+ version 2016-05-31.
+
+ :param copy_source: Specifies the name of the source page blob snapshot. This value is a URL of
+ up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it
+ would appear in a request URI. The source blob must either be public or must be authenticated
+ via a shared access signature.
+ :type copy_source: str
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param modified_access_conditions: Parameter group.
+ :type modified_access_conditions: ~azure.storage.blob.models.ModifiedAccessConditions
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+
+ _if_modified_since = None
+ _if_unmodified_since = None
+ _if_match = None
+ _if_none_match = None
+ _if_tags = None
+ if modified_access_conditions is not None:
+ _if_modified_since = modified_access_conditions.if_modified_since
+ _if_unmodified_since = modified_access_conditions.if_unmodified_since
+ _if_match = modified_access_conditions.if_match
+ _if_none_match = modified_access_conditions.if_none_match
+ _if_tags = modified_access_conditions.if_tags
+ comp = "incrementalcopy"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.copy_incremental.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ if _if_modified_since is not None:
+ header_parameters['If-Modified-Since'] = self._serialize.header("if_modified_since", _if_modified_since, 'rfc-1123')
+ if _if_unmodified_since is not None:
+ header_parameters['If-Unmodified-Since'] = self._serialize.header("if_unmodified_since", _if_unmodified_since, 'rfc-1123')
+ if _if_match is not None:
+ header_parameters['If-Match'] = self._serialize.header("if_match", _if_match, 'str')
+ if _if_none_match is not None:
+ header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str')
+ if _if_tags is not None:
+ header_parameters['x-ms-if-tags'] = self._serialize.header("if_tags", _if_tags, 'str')
+ header_parameters['x-ms-copy-source'] = self._serialize.header("copy_source", copy_source, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.put(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['ETag']=self._deserialize('str', response.headers.get('ETag'))
+ response_headers['Last-Modified']=self._deserialize('rfc-1123', response.headers.get('Last-Modified'))
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-copy-id']=self._deserialize('str', response.headers.get('x-ms-copy-id'))
+ response_headers['x-ms-copy-status']=self._deserialize('str', response.headers.get('x-ms-copy-status'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ copy_incremental.metadata = {'url': '/{containerName}/{blob}'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_service_operations.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_service_operations.py
new file mode 100644
index 00000000000..63628418ddd
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_generated/operations/_service_operations.py
@@ -0,0 +1,710 @@
+# coding=utf-8
+# --------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for license information.
+# Code generated by Microsoft (R) AutoRest Code Generator.
+# Changes may cause incorrect behavior and will be lost if the code is regenerated.
+# --------------------------------------------------------------------------
+from typing import TYPE_CHECKING
+import warnings
+
+from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
+from azure.core.pipeline import PipelineResponse
+from azure.core.pipeline.transport import HttpRequest, HttpResponse
+
+from .. import models as _models
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import,ungrouped-imports
+ from typing import Any, Callable, Dict, Generic, IO, List, Optional, TypeVar, Union
+
+ T = TypeVar('T')
+ ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
+
+class ServiceOperations(object):
+ """ServiceOperations operations.
+
+ You should not instantiate this class directly. Instead, you should create a Client instance that
+ instantiates it for you and attaches it as an attribute.
+
+ :ivar models: Alias to model classes used in this operation group.
+ :type models: ~azure.storage.blob.models
+ :param client: Client for service requests.
+ :param config: Configuration of service client.
+ :param serializer: An object model serializer.
+ :param deserializer: An object model deserializer.
+ """
+
+ models = _models
+
+ def __init__(self, client, config, serializer, deserializer):
+ self._client = client
+ self._serialize = serializer
+ self._deserialize = deserializer
+ self._config = config
+
+ def set_properties(
+ self,
+ storage_service_properties, # type: "_models.StorageServiceProperties"
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Sets properties for a storage account's Blob service endpoint, including properties for Storage
+ Analytics and CORS (Cross-Origin Resource Sharing) rules.
+
+ :param storage_service_properties: The StorageService properties.
+ :type storage_service_properties: ~azure.storage.blob.models.StorageServiceProperties
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "service"
+ comp = "properties"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.set_properties.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(storage_service_properties, 'StorageServiceProperties', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [202]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ set_properties.metadata = {'url': '/'} # type: ignore
+
+ def get_properties(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.StorageServiceProperties"
+ """gets the properties of a storage account's Blob service, including properties for Storage
+ Analytics and CORS (Cross-Origin Resource Sharing) rules.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: StorageServiceProperties, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.StorageServiceProperties
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.StorageServiceProperties"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "service"
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_properties.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ deserialized = self._deserialize('StorageServiceProperties', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_properties.metadata = {'url': '/'} # type: ignore
+
+ def get_statistics(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.StorageServiceStats"
+ """Retrieves statistics related to replication for the Blob service. It is only available on the
+ secondary location endpoint when read-access geo-redundant replication is enabled for the
+ storage account.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: StorageServiceStats, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.StorageServiceStats
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.StorageServiceStats"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "service"
+ comp = "stats"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_statistics.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('StorageServiceStats', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_statistics.metadata = {'url': '/'} # type: ignore
+
+ def list_containers_segment(
+ self,
+ prefix=None, # type: Optional[str]
+ marker=None, # type: Optional[str]
+ maxresults=None, # type: Optional[int]
+ include=None, # type: Optional[List[Union[str, "_models.ListContainersIncludeType"]]]
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.ListContainersSegmentResponse"
+ """The List Containers Segment operation returns a list of the containers under the specified
+ account.
+
+ :param prefix: Filters the results to return only containers whose name begins with the
+ specified prefix.
+ :type prefix: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :param include: Include this parameter to specify that the container's metadata be returned as
+ part of the response body.
+ :type include: list[str or ~azure.storage.blob.models.ListContainersIncludeType]
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: ListContainersSegmentResponse, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.ListContainersSegmentResponse
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.ListContainersSegmentResponse"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "list"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.list_containers_segment.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if prefix is not None:
+ query_parameters['prefix'] = self._serialize.query("prefix", prefix, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+ if include is not None:
+ query_parameters['include'] = self._serialize.query("include", include, '[str]', div=',')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ deserialized = self._deserialize('ListContainersSegmentResponse', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ list_containers_segment.metadata = {'url': '/'} # type: ignore
+
+ def get_user_delegation_key(
+ self,
+ key_info, # type: "_models.KeyInfo"
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.UserDelegationKey"
+ """Retrieves a user delegation key for the Blob service. This is only a valid operation when using
+ bearer token authentication.
+
+ :param key_info: Key information.
+ :type key_info: ~azure.storage.blob.models.KeyInfo
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: UserDelegationKey, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.UserDelegationKey
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.UserDelegationKey"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "service"
+ comp = "userdelegationkey"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_user_delegation_key.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(key_info, 'KeyInfo', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('UserDelegationKey', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ get_user_delegation_key.metadata = {'url': '/'} # type: ignore
+
+ def get_account_info(
+ self,
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ """Returns the sku name and account kind.
+
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: None, or the result of cls(response)
+ :rtype: None
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[None]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ restype = "account"
+ comp = "properties"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.get_account_info.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['restype'] = self._serialize.query("restype", restype, 'str')
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ response_headers['x-ms-sku-name']=self._deserialize('str', response.headers.get('x-ms-sku-name'))
+ response_headers['x-ms-account-kind']=self._deserialize('str', response.headers.get('x-ms-account-kind'))
+ response_headers['x-ms-is-hns-enabled']=self._deserialize('bool', response.headers.get('x-ms-is-hns-enabled'))
+
+ if cls:
+ return cls(pipeline_response, None, response_headers)
+
+ get_account_info.metadata = {'url': '/'} # type: ignore
+
+ def submit_batch(
+ self,
+ content_length, # type: int
+ multipart_content_type, # type: str
+ body, # type: IO
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> IO
+ """The Batch operation allows multiple API calls to be embedded into a single HTTP request.
+
+ :param content_length: The length of the request.
+ :type content_length: long
+ :param multipart_content_type: Required. The value of this header must be multipart/mixed with
+ a batch boundary. Example header value: multipart/mixed; boundary=batch_:code:``.
+ :type multipart_content_type: str
+ :param body: Initial data.
+ :type body: IO
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: IO, or the result of cls(response)
+ :rtype: IO
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType[IO]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "batch"
+ content_type = kwargs.pop("content_type", "application/xml")
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.submit_batch.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['Content-Length'] = self._serialize.header("content_length", content_length, 'long')
+ header_parameters['Content-Type'] = self._serialize.header("multipart_content_type", multipart_content_type, 'str')
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ body_content_kwargs = {} # type: Dict[str, Any]
+ body_content = self._serialize.body(body, 'IO', is_xml=True)
+ body_content_kwargs['content'] = body_content
+ request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
+ pipeline_response = self._client._pipeline.run(request, stream=True, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['Content-Type']=self._deserialize('str', response.headers.get('Content-Type'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ deserialized = response.stream_download(self._client._pipeline)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ submit_batch.metadata = {'url': '/'} # type: ignore
+
+ def filter_blobs(
+ self,
+ timeout=None, # type: Optional[int]
+ request_id_parameter=None, # type: Optional[str]
+ where=None, # type: Optional[str]
+ marker=None, # type: Optional[str]
+ maxresults=None, # type: Optional[int]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> "_models.FilterBlobSegment"
+ """The Filter Blobs operation enables callers to list blobs across all containers whose tags match
+ a given search expression. Filter blobs searches across all containers within a storage
+ account but can be scoped within the expression to a single container.
+
+ :param timeout: The timeout parameter is expressed in seconds. For more information, see
+ :code:`Setting
+ Timeouts for Blob Service Operations.`.
+ :type timeout: int
+ :param request_id_parameter: Provides a client-generated, opaque value with a 1 KB character
+ limit that is recorded in the analytics logs when storage analytics logging is enabled.
+ :type request_id_parameter: str
+ :param where: Filters the results to return only to return only blobs whose tags match the
+ specified expression.
+ :type where: str
+ :param marker: A string value that identifies the portion of the list of containers to be
+ returned with the next listing operation. The operation returns the NextMarker value within the
+ response body if the listing operation did not return all containers remaining to be listed
+ with the current page. The NextMarker value can be used as the value for the marker parameter
+ in a subsequent call to request the next page of list items. The marker value is opaque to the
+ client.
+ :type marker: str
+ :param maxresults: Specifies the maximum number of containers to return. If the request does
+ not specify maxresults, or specifies a value greater than 5000, the server will return up to
+ 5000 items. Note that if the listing operation crosses a partition boundary, then the service
+ will return a continuation token for retrieving the remainder of the results. For this reason,
+ it is possible that the service will return fewer results than specified by maxresults, or than
+ the default of 5000.
+ :type maxresults: int
+ :keyword callable cls: A custom type or function that will be passed the direct response
+ :return: FilterBlobSegment, or the result of cls(response)
+ :rtype: ~azure.storage.blob.models.FilterBlobSegment
+ :raises: ~azure.core.exceptions.HttpResponseError
+ """
+ cls = kwargs.pop('cls', None) # type: ClsType["_models.FilterBlobSegment"]
+ error_map = {
+ 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError
+ }
+ error_map.update(kwargs.pop('error_map', {}))
+ comp = "blobs"
+ accept = "application/xml"
+
+ # Construct URL
+ url = self.filter_blobs.metadata['url'] # type: ignore
+ path_format_arguments = {
+ 'url': self._serialize.url("self._config.url", self._config.url, 'str', skip_quote=True),
+ }
+ url = self._client.format_url(url, **path_format_arguments)
+
+ # Construct parameters
+ query_parameters = {} # type: Dict[str, Any]
+ query_parameters['comp'] = self._serialize.query("comp", comp, 'str')
+ if timeout is not None:
+ query_parameters['timeout'] = self._serialize.query("timeout", timeout, 'int', minimum=0)
+ if where is not None:
+ query_parameters['where'] = self._serialize.query("where", where, 'str')
+ if marker is not None:
+ query_parameters['marker'] = self._serialize.query("marker", marker, 'str')
+ if maxresults is not None:
+ query_parameters['maxresults'] = self._serialize.query("maxresults", maxresults, 'int', minimum=1)
+
+ # Construct headers
+ header_parameters = {} # type: Dict[str, Any]
+ header_parameters['x-ms-version'] = self._serialize.header("self._config.version", self._config.version, 'str')
+ if request_id_parameter is not None:
+ header_parameters['x-ms-client-request-id'] = self._serialize.header("request_id_parameter", request_id_parameter, 'str')
+ header_parameters['Accept'] = self._serialize.header("accept", accept, 'str')
+
+ request = self._client.get(url, query_parameters, header_parameters)
+ pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
+ response = pipeline_response.http_response
+
+ if response.status_code not in [200]:
+ map_error(status_code=response.status_code, response=response, error_map=error_map)
+ error = self._deserialize.failsafe_deserialize(_models.StorageError, response)
+ raise HttpResponseError(response=response, model=error)
+
+ response_headers = {}
+ response_headers['x-ms-client-request-id']=self._deserialize('str', response.headers.get('x-ms-client-request-id'))
+ response_headers['x-ms-request-id']=self._deserialize('str', response.headers.get('x-ms-request-id'))
+ response_headers['x-ms-version']=self._deserialize('str', response.headers.get('x-ms-version'))
+ response_headers['Date']=self._deserialize('rfc-1123', response.headers.get('Date'))
+ deserialized = self._deserialize('FilterBlobSegment', pipeline_response)
+
+ if cls:
+ return cls(pipeline_response, deserialized, response_headers)
+
+ return deserialized
+ filter_blobs.metadata = {'url': '/'} # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_lease.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_lease.py
new file mode 100644
index 00000000000..d495d6e2dfb
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_lease.py
@@ -0,0 +1,331 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import uuid
+
+from typing import ( # pylint: disable=unused-import
+ Union, Optional, Any, TypeVar, TYPE_CHECKING
+)
+
+from azure.core.exceptions import HttpResponseError
+from azure.core.tracing.decorator import distributed_trace
+
+from ._shared.response_handlers import return_response_headers, process_storage_error
+from ._serialize import get_modify_conditions
+
+if TYPE_CHECKING:
+ from datetime import datetime
+
+ BlobClient = TypeVar("BlobClient")
+ ContainerClient = TypeVar("ContainerClient")
+
+
+class BlobLeaseClient(object):
+ """Creates a new BlobLeaseClient.
+
+ This client provides lease operations on a BlobClient or ContainerClient.
+
+ :ivar str id:
+ The ID of the lease currently being maintained. This will be `None` if no
+ lease has yet been acquired.
+ :ivar str etag:
+ The ETag of the lease currently being maintained. This will be `None` if no
+ lease has yet been acquired or modified.
+ :ivar ~datetime.datetime last_modified:
+ The last modified timestamp of the lease currently being maintained.
+ This will be `None` if no lease has yet been acquired or modified.
+
+ :param client:
+ The client of the blob or container to lease.
+ :type client: ~azure.storage.blob.BlobClient or
+ ~azure.storage.blob.ContainerClient
+ :param str lease_id:
+ A string representing the lease ID of an existing lease. This value does not
+ need to be specified in order to acquire a new lease, or break one.
+ """
+ def __init__(
+ self, client, lease_id=None
+ ): # pylint: disable=missing-client-constructor-parameter-credential,missing-client-constructor-parameter-kwargs
+ # type: (Union[BlobClient, ContainerClient], Optional[str]) -> None
+ self.id = lease_id or str(uuid.uuid4())
+ self.last_modified = None
+ self.etag = None
+ if hasattr(client, 'blob_name'):
+ self._client = client._client.blob # type: ignore # pylint: disable=protected-access
+ elif hasattr(client, 'container_name'):
+ self._client = client._client.container # type: ignore # pylint: disable=protected-access
+ else:
+ raise TypeError("Lease must use either BlobClient or ContainerClient.")
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ self.release()
+
+ @distributed_trace
+ def acquire(self, lease_duration=-1, **kwargs):
+ # type: (int, **Any) -> None
+ """Requests a new lease.
+
+ If the container does not have an active lease, the Blob service creates a
+ lease on the container and returns a new lease ID.
+
+ :param int lease_duration:
+ Specifies the duration of the lease, in seconds, or negative one
+ (-1) for a lease that never expires. A non-infinite lease can be
+ between 15 and 60 seconds. A lease duration cannot be changed
+ using renew or change. Default is -1 (infinite lease).
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :rtype: None
+ """
+ mod_conditions = get_modify_conditions(kwargs)
+ try:
+ response = self._client.acquire_lease(
+ timeout=kwargs.pop('timeout', None),
+ duration=lease_duration,
+ proposed_lease_id=self.id,
+ modified_access_conditions=mod_conditions,
+ cls=return_response_headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ self.id = response.get('lease_id') # type: str
+ self.last_modified = response.get('last_modified') # type: datetime
+ self.etag = response.get('etag') # type: str
+
+ @distributed_trace
+ def renew(self, **kwargs):
+ # type: (Any) -> None
+ """Renews the lease.
+
+ The lease can be renewed if the lease ID specified in the
+ lease client matches that associated with the container or blob. Note that
+ the lease may be renewed even if it has expired as long as the container
+ or blob has not been leased again since the expiration of that lease. When you
+ renew a lease, the lease duration clock resets.
+
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :return: None
+ """
+ mod_conditions = get_modify_conditions(kwargs)
+ try:
+ response = self._client.renew_lease(
+ lease_id=self.id,
+ timeout=kwargs.pop('timeout', None),
+ modified_access_conditions=mod_conditions,
+ cls=return_response_headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ self.etag = response.get('etag') # type: str
+ self.id = response.get('lease_id') # type: str
+ self.last_modified = response.get('last_modified') # type: datetime
+
+ @distributed_trace
+ def release(self, **kwargs):
+ # type: (Any) -> None
+ """Release the lease.
+
+ The lease may be released if the client lease id specified matches
+ that associated with the container or blob. Releasing the lease allows another client
+ to immediately acquire the lease for the container or blob as soon as the release is complete.
+
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :return: None
+ """
+ mod_conditions = get_modify_conditions(kwargs)
+ try:
+ response = self._client.release_lease(
+ lease_id=self.id,
+ timeout=kwargs.pop('timeout', None),
+ modified_access_conditions=mod_conditions,
+ cls=return_response_headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ self.etag = response.get('etag') # type: str
+ self.id = response.get('lease_id') # type: str
+ self.last_modified = response.get('last_modified') # type: datetime
+
+ @distributed_trace
+ def change(self, proposed_lease_id, **kwargs):
+ # type: (str, Any) -> None
+ """Change the lease ID of an active lease.
+
+ :param str proposed_lease_id:
+ Proposed lease ID, in a GUID string format. The Blob service returns 400
+ (Invalid request) if the proposed lease ID is not in the correct format.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str etag:
+ An ETag value, or the wildcard character (*). Used to check if the resource has changed,
+ and act according to the condition specified by the `match_condition` parameter.
+ :keyword ~azure.core.MatchConditions match_condition:
+ The match condition to use upon the etag.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :return: None
+ """
+ mod_conditions = get_modify_conditions(kwargs)
+ try:
+ response = self._client.change_lease(
+ lease_id=self.id,
+ proposed_lease_id=proposed_lease_id,
+ timeout=kwargs.pop('timeout', None),
+ modified_access_conditions=mod_conditions,
+ cls=return_response_headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ self.etag = response.get('etag') # type: str
+ self.id = response.get('lease_id') # type: str
+ self.last_modified = response.get('last_modified') # type: datetime
+
+ @distributed_trace
+ def break_lease(self, lease_break_period=None, **kwargs):
+ # type: (Optional[int], Any) -> int
+ """Break the lease, if the container or blob has an active lease.
+
+ Once a lease is broken, it cannot be renewed. Any authorized request can break the lease;
+ the request is not required to specify a matching lease ID. When a lease
+ is broken, the lease break period is allowed to elapse, during which time
+ no lease operation except break and release can be performed on the container or blob.
+ When a lease is successfully broken, the response indicates the interval
+ in seconds until a new lease can be acquired.
+
+ :param int lease_break_period:
+ This is the proposed duration of seconds that the lease
+ should continue before it is broken, between 0 and 60 seconds. This
+ break period is only used if it is shorter than the time remaining
+ on the lease. If longer, the time remaining on the lease is used.
+ A new lease will not be available before the break period has
+ expired, but the lease may be held for longer than the break
+ period. If this header does not appear with a break
+ operation, a fixed-duration lease breaks after the remaining lease
+ period elapses, and an infinite lease breaks immediately.
+ :keyword ~datetime.datetime if_modified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only
+ if the resource has been modified since the specified time.
+ :keyword ~datetime.datetime if_unmodified_since:
+ A DateTime value. Azure expects the date value passed in to be UTC.
+ If timezone is included, any non-UTC datetimes will be converted to UTC.
+ If a date is passed in without timezone info, it is assumed to be UTC.
+ Specify this header to perform the operation only if
+ the resource has not been modified since the specified date/time.
+ :keyword str if_tags_match_condition:
+ Specify a SQL where clause on blob tags to operate only on blob with a matching value.
+ eg. ``\"\\\"tagname\\\"='my tag'\"``
+
+ .. versionadded:: 12.4.0
+
+ :keyword int timeout:
+ The timeout parameter is expressed in seconds.
+ :return: Approximate time remaining in the lease period, in seconds.
+ :rtype: int
+ """
+ mod_conditions = get_modify_conditions(kwargs)
+ try:
+ response = self._client.break_lease(
+ timeout=kwargs.pop('timeout', None),
+ break_period=lease_break_period,
+ modified_access_conditions=mod_conditions,
+ cls=return_response_headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
+ return response.get('lease_time') # type: ignore
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_list_blobs_helper.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_list_blobs_helper.py
new file mode 100644
index 00000000000..faf9433c6fb
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_list_blobs_helper.py
@@ -0,0 +1,244 @@
+# pylint: disable=too-many-lines
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+try:
+ from urllib.parse import unquote
+except ImportError:
+ from urllib import unquote
+from azure.core.paging import PageIterator, ItemPaged
+from azure.core.exceptions import HttpResponseError
+from ._deserialize import get_blob_properties_from_generated_code, parse_tags
+from ._generated.models import BlobItemInternal, BlobPrefix as GenBlobPrefix, FilterBlobItem
+from ._models import BlobProperties, FilteredBlob
+from ._shared.models import DictMixin
+from ._shared.response_handlers import return_context_and_deserialized, process_storage_error
+
+
+class BlobPropertiesPaged(PageIterator):
+ """An Iterable of Blob properties.
+
+ :ivar str service_endpoint: The service URL.
+ :ivar str prefix: A blob name prefix being used to filter the list.
+ :ivar str marker: The continuation token of the current page of results.
+ :ivar int results_per_page: The maximum number of results retrieved per API call.
+ :ivar str continuation_token: The continuation token to retrieve the next page of results.
+ :ivar str location_mode: The location mode being used to list results. The available
+ options include "primary" and "secondary".
+ :ivar current_page: The current page of listed results.
+ :vartype current_page: list(~azure.storage.blob.BlobProperties)
+ :ivar str container: The container that the blobs are listed from.
+ :ivar str delimiter: A delimiting character used for hierarchy listing.
+
+ :param callable command: Function to retrieve the next page of items.
+ :param str container: The name of the container.
+ :param str prefix: Filters the results to return only blobs whose names
+ begin with the specified prefix.
+ :param int results_per_page: The maximum number of blobs to retrieve per
+ call.
+ :param str continuation_token: An opaque continuation token.
+ :param str delimiter:
+ Used to capture blobs whose names begin with the same substring up to
+ the appearance of the delimiter character. The delimiter may be a single
+ character or a string.
+ :param location_mode: Specifies the location the request should be sent to.
+ This mode only applies for RA-GRS accounts which allow secondary read access.
+ Options include 'primary' or 'secondary'.
+ """
+ def __init__(
+ self, command,
+ container=None,
+ prefix=None,
+ results_per_page=None,
+ continuation_token=None,
+ delimiter=None,
+ location_mode=None):
+ super(BlobPropertiesPaged, self).__init__(
+ get_next=self._get_next_cb,
+ extract_data=self._extract_data_cb,
+ continuation_token=continuation_token or ""
+ )
+ self._command = command
+ self.service_endpoint = None
+ self.prefix = prefix
+ self.marker = None
+ self.results_per_page = results_per_page
+ self.container = container
+ self.delimiter = delimiter
+ self.current_page = None
+ self.location_mode = location_mode
+
+ def _get_next_cb(self, continuation_token):
+ try:
+ return self._command(
+ prefix=self.prefix,
+ marker=continuation_token or None,
+ maxresults=self.results_per_page,
+ cls=return_context_and_deserialized,
+ use_location=self.location_mode)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _extract_data_cb(self, get_next_return):
+ self.location_mode, self._response = get_next_return
+ self.service_endpoint = self._response.service_endpoint
+ self.prefix = self._response.prefix
+ self.marker = self._response.marker
+ self.results_per_page = self._response.max_results
+ self.container = self._response.container_name
+ self.current_page = [self._build_item(item) for item in self._response.segment.blob_items]
+
+ return self._response.next_marker or None, self.current_page
+
+ def _build_item(self, item):
+ if isinstance(item, BlobProperties):
+ return item
+ if isinstance(item, BlobItemInternal):
+ blob = get_blob_properties_from_generated_code(item) # pylint: disable=protected-access
+ blob.container = self.container
+ return blob
+ return item
+
+
+class BlobPrefixPaged(BlobPropertiesPaged):
+ def __init__(self, *args, **kwargs):
+ super(BlobPrefixPaged, self).__init__(*args, **kwargs)
+ self.name = self.prefix
+
+ def _extract_data_cb(self, get_next_return):
+ continuation_token, _ = super(BlobPrefixPaged, self)._extract_data_cb(get_next_return)
+ self.current_page = self._response.segment.blob_prefixes + self._response.segment.blob_items
+ self.current_page = [self._build_item(item) for item in self.current_page]
+ self.delimiter = self._response.delimiter
+
+ return continuation_token, self.current_page
+
+ def _build_item(self, item):
+ item = super(BlobPrefixPaged, self)._build_item(item)
+ if isinstance(item, GenBlobPrefix):
+ if item.name.encoded:
+ name = unquote(item.name.content)
+ else:
+ name = item.name.content
+ return BlobPrefix(
+ self._command,
+ container=self.container,
+ prefix=name,
+ results_per_page=self.results_per_page,
+ location_mode=self.location_mode)
+ return item
+
+
+class BlobPrefix(ItemPaged, DictMixin):
+ """An Iterable of Blob properties.
+
+ Returned from walk_blobs when a delimiter is used.
+ Can be thought of as a virtual blob directory.
+
+ :ivar str name: The prefix, or "directory name" of the blob.
+ :ivar str service_endpoint: The service URL.
+ :ivar str prefix: A blob name prefix being used to filter the list.
+ :ivar str marker: The continuation token of the current page of results.
+ :ivar int results_per_page: The maximum number of results retrieved per API call.
+ :ivar str next_marker: The continuation token to retrieve the next page of results.
+ :ivar str location_mode: The location mode being used to list results. The available
+ options include "primary" and "secondary".
+ :ivar current_page: The current page of listed results.
+ :vartype current_page: list(~azure.storage.blob.BlobProperties)
+ :ivar str container: The container that the blobs are listed from.
+ :ivar str delimiter: A delimiting character used for hierarchy listing.
+
+ :param callable command: Function to retrieve the next page of items.
+ :param str prefix: Filters the results to return only blobs whose names
+ begin with the specified prefix.
+ :param int results_per_page: The maximum number of blobs to retrieve per
+ call.
+ :param str marker: An opaque continuation token.
+ :param str delimiter:
+ Used to capture blobs whose names begin with the same substring up to
+ the appearance of the delimiter character. The delimiter may be a single
+ character or a string.
+ :param location_mode: Specifies the location the request should be sent to.
+ This mode only applies for RA-GRS accounts which allow secondary read access.
+ Options include 'primary' or 'secondary'.
+ """
+ def __init__(self, *args, **kwargs):
+ super(BlobPrefix, self).__init__(*args, page_iterator_class=BlobPrefixPaged, **kwargs)
+ self.name = kwargs.get('prefix')
+ self.prefix = kwargs.get('prefix')
+ self.results_per_page = kwargs.get('results_per_page')
+ self.container = kwargs.get('container')
+ self.delimiter = kwargs.get('delimiter')
+ self.location_mode = kwargs.get('location_mode')
+
+
+class FilteredBlobPaged(PageIterator):
+ """An Iterable of Blob properties.
+
+ :ivar str service_endpoint: The service URL.
+ :ivar str prefix: A blob name prefix being used to filter the list.
+ :ivar str marker: The continuation token of the current page of results.
+ :ivar int results_per_page: The maximum number of results retrieved per API call.
+ :ivar str continuation_token: The continuation token to retrieve the next page of results.
+ :ivar str location_mode: The location mode being used to list results. The available
+ options include "primary" and "secondary".
+ :ivar current_page: The current page of listed results.
+ :vartype current_page: list(~azure.storage.blob.FilteredBlob)
+ :ivar str container: The container that the blobs are listed from.
+
+ :param callable command: Function to retrieve the next page of items.
+ :param str container: The name of the container.
+ :param int results_per_page: The maximum number of blobs to retrieve per
+ call.
+ :param str continuation_token: An opaque continuation token.
+ :param location_mode: Specifies the location the request should be sent to.
+ This mode only applies for RA-GRS accounts which allow secondary read access.
+ Options include 'primary' or 'secondary'.
+ """
+ def __init__(
+ self, command,
+ container=None,
+ results_per_page=None,
+ continuation_token=None,
+ location_mode=None):
+ super(FilteredBlobPaged, self).__init__(
+ get_next=self._get_next_cb,
+ extract_data=self._extract_data_cb,
+ continuation_token=continuation_token or ""
+ )
+ self._command = command
+ self.service_endpoint = None
+ self.marker = continuation_token
+ self.results_per_page = results_per_page
+ self.container = container
+ self.current_page = None
+ self.location_mode = location_mode
+
+ def _get_next_cb(self, continuation_token):
+ try:
+ return self._command(
+ marker=continuation_token or None,
+ maxresults=self.results_per_page,
+ cls=return_context_and_deserialized,
+ use_location=self.location_mode)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _extract_data_cb(self, get_next_return):
+ self.location_mode, self._response = get_next_return
+ self.service_endpoint = self._response.service_endpoint
+ self.marker = self._response.next_marker
+ self.current_page = [self._build_item(item) for item in self._response.blobs]
+
+ return self._response.next_marker or None, self.current_page
+
+ @staticmethod
+ def _build_item(item):
+ if isinstance(item, FilterBlobItem):
+ tags = parse_tags(item.tags)
+ blob = FilteredBlob(name=item.name, container_name=item.container_name, tags=tags)
+ return blob
+ return item
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_models.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_models.py
new file mode 100644
index 00000000000..c67806d1f25
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_models.py
@@ -0,0 +1,1259 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=too-few-public-methods, too-many-instance-attributes
+# pylint: disable=super-init-not-called, too-many-lines
+
+from enum import Enum
+
+from azure.core.paging import PageIterator
+from azure.core.exceptions import HttpResponseError
+from ._generated.models import ArrowField
+
+from ._shared import decode_base64_to_bytes
+from ._shared.response_handlers import return_context_and_deserialized, process_storage_error
+from ._shared.models import DictMixin, get_enum_value
+from ._generated.models import Logging as GeneratedLogging
+from ._generated.models import Metrics as GeneratedMetrics
+from ._generated.models import RetentionPolicy as GeneratedRetentionPolicy
+from ._generated.models import StaticWebsite as GeneratedStaticWebsite
+from ._generated.models import CorsRule as GeneratedCorsRule
+from ._generated.models import AccessPolicy as GenAccessPolicy
+
+
+class BlobType(str, Enum):
+
+ BlockBlob = "BlockBlob"
+ PageBlob = "PageBlob"
+ AppendBlob = "AppendBlob"
+
+
+class BlockState(str, Enum):
+ """Block blob block types."""
+
+ Committed = 'Committed' #: Committed blocks.
+ Latest = 'Latest' #: Latest blocks.
+ Uncommitted = 'Uncommitted' #: Uncommitted blocks.
+
+
+class StandardBlobTier(str, Enum):
+ """
+ Specifies the blob tier to set the blob to. This is only applicable for
+ block blobs on standard storage accounts.
+ """
+
+ Archive = 'Archive' #: Archive
+ Cool = 'Cool' #: Cool
+ Hot = 'Hot' #: Hot
+
+
+class PremiumPageBlobTier(str, Enum):
+ """
+ Specifies the page blob tier to set the blob to. This is only applicable to page
+ blobs on premium storage accounts. Please take a look at:
+ https://docs.microsoft.com/en-us/azure/storage/storage-premium-storage#scalability-and-performance-targets
+ for detailed information on the corresponding IOPS and throughput per PageBlobTier.
+ """
+
+ P4 = 'P4' #: P4 Tier
+ P6 = 'P6' #: P6 Tier
+ P10 = 'P10' #: P10 Tier
+ P20 = 'P20' #: P20 Tier
+ P30 = 'P30' #: P30 Tier
+ P40 = 'P40' #: P40 Tier
+ P50 = 'P50' #: P50 Tier
+ P60 = 'P60' #: P60 Tier
+
+
+class QuickQueryDialect(str, Enum):
+ """Specifies the quick query input/output dialect."""
+
+ DelimitedText = 'DelimitedTextDialect'
+ DelimitedJson = 'DelimitedJsonDialect'
+ Parquet = 'ParquetDialect'
+
+
+class SequenceNumberAction(str, Enum):
+ """Sequence number actions."""
+
+ Increment = 'increment'
+ """
+ Increments the value of the sequence number by 1. If specifying this option,
+ do not include the x-ms-blob-sequence-number header.
+ """
+
+ Max = 'max'
+ """
+ Sets the sequence number to be the higher of the value included with the
+ request and the value currently stored for the blob.
+ """
+
+ Update = 'update'
+ """Sets the sequence number to the value included with the request."""
+
+
+class PublicAccess(str, Enum):
+ """
+ Specifies whether data in the container may be accessed publicly and the level of access.
+ """
+
+ OFF = 'off'
+ """
+ Specifies that there is no public read access for both the container and blobs within the container.
+ Clients cannot enumerate the containers within the storage account as well as the blobs within the container.
+ """
+
+ Blob = 'blob'
+ """
+ Specifies public read access for blobs. Blob data within this container can be read
+ via anonymous request, but container data is not available. Clients cannot enumerate
+ blobs within the container via anonymous request.
+ """
+
+ Container = 'container'
+ """
+ Specifies full public read access for container and blob data. Clients can enumerate
+ blobs within the container via anonymous request, but cannot enumerate containers
+ within the storage account.
+ """
+
+
+class BlobImmutabilityPolicyMode(str, Enum):
+ """
+ Specifies the immutability policy mode to set on the blob.
+ "Mutable" can only be returned by service, don't set to "Mutable".
+ """
+
+ Unlocked = "Unlocked"
+ Locked = "Locked"
+ Mutable = "Mutable"
+
+
+class BlobAnalyticsLogging(GeneratedLogging):
+ """Azure Analytics Logging settings.
+
+ :keyword str version:
+ The version of Storage Analytics to configure. The default value is 1.0.
+ :keyword bool delete:
+ Indicates whether all delete requests should be logged. The default value is `False`.
+ :keyword bool read:
+ Indicates whether all read requests should be logged. The default value is `False`.
+ :keyword bool write:
+ Indicates whether all write requests should be logged. The default value is `False`.
+ :keyword ~azure.storage.blob.RetentionPolicy retention_policy:
+ Determines how long the associated data should persist. If not specified the retention
+ policy will be disabled by default.
+ """
+
+ def __init__(self, **kwargs):
+ self.version = kwargs.get('version', u'1.0')
+ self.delete = kwargs.get('delete', False)
+ self.read = kwargs.get('read', False)
+ self.write = kwargs.get('write', False)
+ self.retention_policy = kwargs.get('retention_policy') or RetentionPolicy()
+
+ @classmethod
+ def _from_generated(cls, generated):
+ if not generated:
+ return cls()
+ return cls(
+ version=generated.version,
+ delete=generated.delete,
+ read=generated.read,
+ write=generated.write,
+ retention_policy=RetentionPolicy._from_generated(generated.retention_policy) # pylint: disable=protected-access
+ )
+
+
+class Metrics(GeneratedMetrics):
+ """A summary of request statistics grouped by API in hour or minute aggregates
+ for blobs.
+
+ :keyword str version:
+ The version of Storage Analytics to configure. The default value is 1.0.
+ :keyword bool enabled:
+ Indicates whether metrics are enabled for the Blob service.
+ The default value is `False`.
+ :keyword bool include_apis:
+ Indicates whether metrics should generate summary statistics for called API operations.
+ :keyword ~azure.storage.blob.RetentionPolicy retention_policy:
+ Determines how long the associated data should persist. If not specified the retention
+ policy will be disabled by default.
+ """
+
+ def __init__(self, **kwargs):
+ self.version = kwargs.get('version', u'1.0')
+ self.enabled = kwargs.get('enabled', False)
+ self.include_apis = kwargs.get('include_apis')
+ self.retention_policy = kwargs.get('retention_policy') or RetentionPolicy()
+
+ @classmethod
+ def _from_generated(cls, generated):
+ if not generated:
+ return cls()
+ return cls(
+ version=generated.version,
+ enabled=generated.enabled,
+ include_apis=generated.include_apis,
+ retention_policy=RetentionPolicy._from_generated(generated.retention_policy) # pylint: disable=protected-access
+ )
+
+
+class RetentionPolicy(GeneratedRetentionPolicy):
+ """The retention policy which determines how long the associated data should
+ persist.
+
+ :param bool enabled:
+ Indicates whether a retention policy is enabled for the storage service.
+ The default value is False.
+ :param int days:
+ Indicates the number of days that metrics or logging or
+ soft-deleted data should be retained. All data older than this value will
+ be deleted. If enabled=True, the number of days must be specified.
+ """
+
+ def __init__(self, enabled=False, days=None):
+ super(RetentionPolicy, self).__init__(enabled=enabled, days=days, allow_permanent_delete=None)
+ if self.enabled and (self.days is None):
+ raise ValueError("If policy is enabled, 'days' must be specified.")
+
+ @classmethod
+ def _from_generated(cls, generated):
+ if not generated:
+ return cls()
+ return cls(
+ enabled=generated.enabled,
+ days=generated.days,
+ )
+
+
+class StaticWebsite(GeneratedStaticWebsite):
+ """The properties that enable an account to host a static website.
+
+ :keyword bool enabled:
+ Indicates whether this account is hosting a static website.
+ The default value is `False`.
+ :keyword str index_document:
+ The default name of the index page under each directory.
+ :keyword str error_document404_path:
+ The absolute path of the custom 404 page.
+ :keyword str default_index_document_path:
+ Absolute path of the default index page.
+ """
+
+ def __init__(self, **kwargs):
+ self.enabled = kwargs.get('enabled', False)
+ if self.enabled:
+ self.index_document = kwargs.get('index_document')
+ self.error_document404_path = kwargs.get('error_document404_path')
+ self.default_index_document_path = kwargs.get('default_index_document_path')
+ else:
+ self.index_document = None
+ self.error_document404_path = None
+ self.default_index_document_path = None
+
+ @classmethod
+ def _from_generated(cls, generated):
+ if not generated:
+ return cls()
+ return cls(
+ enabled=generated.enabled,
+ index_document=generated.index_document,
+ error_document404_path=generated.error_document404_path,
+ default_index_document_path=generated.default_index_document_path
+ )
+
+
+class CorsRule(GeneratedCorsRule):
+ """CORS is an HTTP feature that enables a web application running under one
+ domain to access resources in another domain. Web browsers implement a
+ security restriction known as same-origin policy that prevents a web page
+ from calling APIs in a different domain; CORS provides a secure way to
+ allow one domain (the origin domain) to call APIs in another domain.
+
+ :param list(str) allowed_origins:
+ A list of origin domains that will be allowed via CORS, or "*" to allow
+ all domains. The list of must contain at least one entry. Limited to 64
+ origin domains. Each allowed origin can have up to 256 characters.
+ :param list(str) allowed_methods:
+ A list of HTTP methods that are allowed to be executed by the origin.
+ The list of must contain at least one entry. For Azure Storage,
+ permitted methods are DELETE, GET, HEAD, MERGE, POST, OPTIONS or PUT.
+ :keyword list(str) allowed_headers:
+ Defaults to an empty list. A list of headers allowed to be part of
+ the cross-origin request. Limited to 64 defined headers and 2 prefixed
+ headers. Each header can be up to 256 characters.
+ :keyword list(str) exposed_headers:
+ Defaults to an empty list. A list of response headers to expose to CORS
+ clients. Limited to 64 defined headers and two prefixed headers. Each
+ header can be up to 256 characters.
+ :keyword int max_age_in_seconds:
+ The number of seconds that the client/browser should cache a
+ preflight response.
+ """
+
+ def __init__(self, allowed_origins, allowed_methods, **kwargs):
+ self.allowed_origins = ','.join(allowed_origins)
+ self.allowed_methods = ','.join(allowed_methods)
+ self.allowed_headers = ','.join(kwargs.get('allowed_headers', []))
+ self.exposed_headers = ','.join(kwargs.get('exposed_headers', []))
+ self.max_age_in_seconds = kwargs.get('max_age_in_seconds', 0)
+
+ @classmethod
+ def _from_generated(cls, generated):
+ return cls(
+ [generated.allowed_origins],
+ [generated.allowed_methods],
+ allowed_headers=[generated.allowed_headers],
+ exposed_headers=[generated.exposed_headers],
+ max_age_in_seconds=generated.max_age_in_seconds,
+ )
+
+
+class ContainerProperties(DictMixin):
+ """Blob container's properties class.
+
+ Returned ``ContainerProperties`` instances expose these values through a
+ dictionary interface, for example: ``container_props["last_modified"]``.
+ Additionally, the container name is available as ``container_props["name"]``.
+
+ :ivar str name:
+ Name of the container.
+ :ivar ~datetime.datetime last_modified:
+ A datetime object representing the last time the container was modified.
+ :ivar str etag:
+ The ETag contains a value that you can use to perform operations
+ conditionally.
+ :ivar ~azure.storage.blob.LeaseProperties lease:
+ Stores all the lease information for the container.
+ :ivar str public_access: Specifies whether data in the container may be accessed
+ publicly and the level of access.
+ :ivar bool has_immutability_policy:
+ Represents whether the container has an immutability policy.
+ :ivar bool has_legal_hold:
+ Represents whether the container has a legal hold.
+ :ivar bool immutable_storage_with_versioning_enabled:
+ Represents whether immutable storage with versioning enabled on the container.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :ivar dict metadata: A dict with name-value pairs to associate with the
+ container as metadata.
+ :ivar ~azure.storage.blob.ContainerEncryptionScope encryption_scope:
+ The default encryption scope configuration for the container.
+ :ivar bool deleted:
+ Whether this container was deleted.
+ :ivar str version:
+ The version of a deleted container.
+ """
+
+ def __init__(self, **kwargs):
+ self.name = None
+ self.last_modified = kwargs.get('Last-Modified')
+ self.etag = kwargs.get('ETag')
+ self.lease = LeaseProperties(**kwargs)
+ self.public_access = kwargs.get('x-ms-blob-public-access')
+ self.has_immutability_policy = kwargs.get('x-ms-has-immutability-policy')
+ self.deleted = None
+ self.version = None
+ self.has_legal_hold = kwargs.get('x-ms-has-legal-hold')
+ self.metadata = kwargs.get('metadata')
+ self.encryption_scope = None
+ self.immutable_storage_with_versioning_enabled = kwargs.get('x-ms-immutable-storage-with-versioning-enabled')
+ default_encryption_scope = kwargs.get('x-ms-default-encryption-scope')
+ if default_encryption_scope:
+ self.encryption_scope = ContainerEncryptionScope(
+ default_encryption_scope=default_encryption_scope,
+ prevent_encryption_scope_override=kwargs.get('x-ms-deny-encryption-scope-override', False)
+ )
+
+ @classmethod
+ def _from_generated(cls, generated):
+ props = cls()
+ props.name = generated.name
+ props.last_modified = generated.properties.last_modified
+ props.etag = generated.properties.etag
+ props.lease = LeaseProperties._from_generated(generated) # pylint: disable=protected-access
+ props.public_access = generated.properties.public_access
+ props.has_immutability_policy = generated.properties.has_immutability_policy
+ props.immutable_storage_with_versioning_enabled = \
+ generated.properties.is_immutable_storage_with_versioning_enabled
+ props.deleted = generated.deleted
+ props.version = generated.version
+ props.has_legal_hold = generated.properties.has_legal_hold
+ props.metadata = generated.metadata
+ props.encryption_scope = ContainerEncryptionScope._from_generated(generated) #pylint: disable=protected-access
+ return props
+
+
+class ContainerPropertiesPaged(PageIterator):
+ """An Iterable of Container properties.
+
+ :ivar str service_endpoint: The service URL.
+ :ivar str prefix: A container name prefix being used to filter the list.
+ :ivar str marker: The continuation token of the current page of results.
+ :ivar int results_per_page: The maximum number of results retrieved per API call.
+ :ivar str continuation_token: The continuation token to retrieve the next page of results.
+ :ivar str location_mode: The location mode being used to list results. The available
+ options include "primary" and "secondary".
+ :ivar current_page: The current page of listed results.
+ :vartype current_page: list(~azure.storage.blob.ContainerProperties)
+
+ :param callable command: Function to retrieve the next page of items.
+ :param str prefix: Filters the results to return only containers whose names
+ begin with the specified prefix.
+ :param int results_per_page: The maximum number of container names to retrieve per
+ call.
+ :param str continuation_token: An opaque continuation token.
+ """
+ def __init__(self, command, prefix=None, results_per_page=None, continuation_token=None):
+ super(ContainerPropertiesPaged, self).__init__(
+ get_next=self._get_next_cb,
+ extract_data=self._extract_data_cb,
+ continuation_token=continuation_token or ""
+ )
+ self._command = command
+ self.service_endpoint = None
+ self.prefix = prefix
+ self.marker = None
+ self.results_per_page = results_per_page
+ self.location_mode = None
+ self.current_page = []
+
+ def _get_next_cb(self, continuation_token):
+ try:
+ return self._command(
+ marker=continuation_token or None,
+ maxresults=self.results_per_page,
+ cls=return_context_and_deserialized,
+ use_location=self.location_mode)
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+ def _extract_data_cb(self, get_next_return):
+ self.location_mode, self._response = get_next_return
+ self.service_endpoint = self._response.service_endpoint
+ self.prefix = self._response.prefix
+ self.marker = self._response.marker
+ self.results_per_page = self._response.max_results
+ self.current_page = [self._build_item(item) for item in self._response.container_items]
+
+ return self._response.next_marker or None, self.current_page
+
+ @staticmethod
+ def _build_item(item):
+ return ContainerProperties._from_generated(item) # pylint: disable=protected-access
+
+
+class ImmutabilityPolicy(DictMixin):
+ """Optional parameters for setting the immutability policy of a blob, blob snapshot or blob version.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :keyword ~datetime.datetime expiry_time:
+ Specifies the date time when the blobs immutability policy is set to expire.
+ :keyword str or ~azure.storage.blob.BlobImmutabilityPolicyMode policy_mode:
+ Specifies the immutability policy mode to set on the blob.
+ Possible values to set include: "Locked", "Unlocked".
+ "Mutable" can only be returned by service, don't set to "Mutable".
+ """
+
+ def __init__(self, **kwargs):
+ self.expiry_time = kwargs.pop('expiry_time', None)
+ self.policy_mode = kwargs.pop('policy_mode', None)
+
+ @classmethod
+ def _from_generated(cls, generated):
+ immutability_policy = cls()
+ immutability_policy.expiry_time = generated.properties.immutability_policy_expires_on
+ immutability_policy.policy_mode = generated.properties.immutability_policy_mode
+ return immutability_policy
+
+
+class BlobProperties(DictMixin):
+ """
+ Blob Properties.
+
+ :ivar str name:
+ The name of the blob.
+ :ivar str container:
+ The container in which the blob resides.
+ :ivar str snapshot:
+ Datetime value that uniquely identifies the blob snapshot.
+ :ivar ~azure.blob.storage.BlobType blob_type:
+ String indicating this blob's type.
+ :ivar dict metadata:
+ Name-value pairs associated with the blob as metadata.
+ :ivar ~datetime.datetime last_modified:
+ A datetime object representing the last time the blob was modified.
+ :ivar str etag:
+ The ETag contains a value that you can use to perform operations
+ conditionally.
+ :ivar int size:
+ The size of the content returned. If the entire blob was requested,
+ the length of blob in bytes. If a subset of the blob was requested, the
+ length of the returned subset.
+ :ivar str content_range:
+ Indicates the range of bytes returned in the event that the client
+ requested a subset of the blob.
+ :ivar int append_blob_committed_block_count:
+ (For Append Blobs) Number of committed blocks in the blob.
+ :ivar bool is_append_blob_sealed:
+ Indicate if the append blob is sealed or not.
+
+ .. versionadded:: 12.4.0
+
+ :ivar int page_blob_sequence_number:
+ (For Page Blobs) Sequence number for page blob used for coordinating
+ concurrent writes.
+ :ivar bool server_encrypted:
+ Set to true if the blob is encrypted on the server.
+ :ivar ~azure.storage.blob.CopyProperties copy:
+ Stores all the copy properties for the blob.
+ :ivar ~azure.storage.blob.ContentSettings content_settings:
+ Stores all the content settings for the blob.
+ :ivar ~azure.storage.blob.LeaseProperties lease:
+ Stores all the lease information for the blob.
+ :ivar ~azure.storage.blob.StandardBlobTier blob_tier:
+ Indicates the access tier of the blob. The hot tier is optimized
+ for storing data that is accessed frequently. The cool storage tier
+ is optimized for storing data that is infrequently accessed and stored
+ for at least a month. The archive tier is optimized for storing
+ data that is rarely accessed and stored for at least six months
+ with flexible latency requirements.
+ :ivar str rehydrate_priority:
+ Indicates the priority with which to rehydrate an archived blob
+ :ivar ~datetime.datetime blob_tier_change_time:
+ Indicates when the access tier was last changed.
+ :ivar bool blob_tier_inferred:
+ Indicates whether the access tier was inferred by the service.
+ If false, it indicates that the tier was set explicitly.
+ :ivar bool deleted:
+ Whether this blob was deleted.
+ :ivar ~datetime.datetime deleted_time:
+ A datetime object representing the time at which the blob was deleted.
+ :ivar int remaining_retention_days:
+ The number of days that the blob will be retained before being permanently deleted by the service.
+ :ivar ~datetime.datetime creation_time:
+ Indicates when the blob was created, in UTC.
+ :ivar str archive_status:
+ Archive status of blob.
+ :ivar str encryption_key_sha256:
+ The SHA-256 hash of the provided encryption key.
+ :ivar str encryption_scope:
+ A predefined encryption scope used to encrypt the data on the service. An encryption
+ scope can be created using the Management API and referenced here by name. If a default
+ encryption scope has been defined at the container, this value will override it if the
+ container-level scope is configured to allow overrides. Otherwise an error will be raised.
+ :ivar bool request_server_encrypted:
+ Whether this blob is encrypted.
+ :ivar list(~azure.storage.blob.ObjectReplicationPolicy) object_replication_source_properties:
+ Only present for blobs that have policy ids and rule ids applied to them.
+
+ .. versionadded:: 12.4.0
+
+ :ivar str object_replication_destination_policy:
+ Represents the Object Replication Policy Id that created this blob.
+
+ .. versionadded:: 12.4.0
+
+ :ivar ~datetime.datetime last_accessed_on:
+ Indicates when the last Read/Write operation was performed on a Blob.
+
+ .. versionadded:: 12.6.0
+
+ :ivar int tag_count:
+ Tags count on this blob.
+
+ .. versionadded:: 12.4.0
+
+ :ivar dict(str, str) tags:
+ 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
+
+ :ivar ~azure.storage.blob.ImmutabilityPolicy immutability_policy:
+ Specifies the immutability policy of a blob, blob snapshot or blob version.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ :ivar bool has_legal_hold:
+ Specified if a legal hold should be set on the blob.
+ Currently this parameter of upload_blob() API is for BlockBlob only.
+
+ .. versionadded:: 12.10.0
+ This was introduced in API version '2020-10-02'.
+
+ """
+
+ def __init__(self, **kwargs):
+ self.name = kwargs.get('name')
+ self.container = None
+ self.snapshot = kwargs.get('x-ms-snapshot')
+ self.version_id = kwargs.get('x-ms-version-id')
+ self.is_current_version = kwargs.get('x-ms-is-current-version')
+ self.blob_type = BlobType(kwargs['x-ms-blob-type']) if kwargs.get('x-ms-blob-type') else None
+ self.metadata = kwargs.get('metadata')
+ self.encrypted_metadata = kwargs.get('encrypted_metadata')
+ self.last_modified = kwargs.get('Last-Modified')
+ self.etag = kwargs.get('ETag')
+ self.size = kwargs.get('Content-Length')
+ self.content_range = kwargs.get('Content-Range')
+ self.append_blob_committed_block_count = kwargs.get('x-ms-blob-committed-block-count')
+ self.is_append_blob_sealed = kwargs.get('x-ms-blob-sealed')
+ self.page_blob_sequence_number = kwargs.get('x-ms-blob-sequence-number')
+ self.server_encrypted = kwargs.get('x-ms-server-encrypted')
+ self.copy = CopyProperties(**kwargs)
+ self.content_settings = ContentSettings(**kwargs)
+ self.lease = LeaseProperties(**kwargs)
+ self.blob_tier = kwargs.get('x-ms-access-tier')
+ self.rehydrate_priority = kwargs.get('x-ms-rehydrate-priority')
+ self.blob_tier_change_time = kwargs.get('x-ms-access-tier-change-time')
+ self.blob_tier_inferred = kwargs.get('x-ms-access-tier-inferred')
+ self.deleted = False
+ self.deleted_time = None
+ self.remaining_retention_days = None
+ self.creation_time = kwargs.get('x-ms-creation-time')
+ self.archive_status = kwargs.get('x-ms-archive-status')
+ self.encryption_key_sha256 = kwargs.get('x-ms-encryption-key-sha256')
+ self.encryption_scope = kwargs.get('x-ms-encryption-scope')
+ self.request_server_encrypted = kwargs.get('x-ms-server-encrypted')
+ self.object_replication_source_properties = kwargs.get('object_replication_source_properties')
+ self.object_replication_destination_policy = kwargs.get('x-ms-or-policy-id')
+ self.last_accessed_on = kwargs.get('x-ms-last-access-time')
+ self.tag_count = kwargs.get('x-ms-tag-count')
+ self.tags = None
+ self.immutability_policy = ImmutabilityPolicy(expiry_time=kwargs.get('x-ms-immutability-policy-until-date'),
+ policy_mode=kwargs.get('x-ms-immutability-policy-mode'))
+ self.has_legal_hold = kwargs.get('x-ms-legal-hold')
+ self.has_versions_only = None
+
+
+class FilteredBlob(DictMixin):
+ """Blob info from a Filter Blobs API call.
+
+ :ivar name: Blob name
+ :type name: str
+ :ivar container_name: Container name.
+ :type container_name: str
+ :ivar tags: Key value pairs of blob tags.
+ :type tags: Dict[str, str]
+ """
+ def __init__(self, **kwargs):
+ self.name = kwargs.get('name', None)
+ self.container_name = kwargs.get('container_name', None)
+ self.tags = kwargs.get('tags', None)
+
+
+class LeaseProperties(DictMixin):
+ """Blob Lease Properties.
+
+ :ivar str status:
+ The lease status of the blob. Possible values: locked|unlocked
+ :ivar str state:
+ Lease state of the blob. Possible values: available|leased|expired|breaking|broken
+ :ivar str duration:
+ When a blob is leased, specifies whether the lease is of infinite or fixed duration.
+ """
+
+ def __init__(self, **kwargs):
+ self.status = get_enum_value(kwargs.get('x-ms-lease-status'))
+ self.state = get_enum_value(kwargs.get('x-ms-lease-state'))
+ self.duration = get_enum_value(kwargs.get('x-ms-lease-duration'))
+
+ @classmethod
+ def _from_generated(cls, generated):
+ lease = cls()
+ lease.status = get_enum_value(generated.properties.lease_status)
+ lease.state = get_enum_value(generated.properties.lease_state)
+ lease.duration = get_enum_value(generated.properties.lease_duration)
+ return lease
+
+
+class ContentSettings(DictMixin):
+ """The content settings of a blob.
+
+ :param str content_type:
+ The content type specified for the blob. If no content type was
+ specified, the default content type is application/octet-stream.
+ :param str content_encoding:
+ If the content_encoding has previously been set
+ for the blob, that value is stored.
+ :param str content_language:
+ If the content_language has previously been set
+ for the blob, that value is stored.
+ :param str content_disposition:
+ content_disposition conveys additional information about how to
+ process the response payload, and also can be used to attach
+ additional metadata. If content_disposition has previously been set
+ for the blob, that value is stored.
+ :param str cache_control:
+ If the cache_control has previously been set for
+ the blob, that value is stored.
+ :param bytearray content_md5:
+ If the content_md5 has been set for the blob, this response
+ header is stored so that the client can check for message content
+ integrity.
+ """
+
+ def __init__(
+ self, content_type=None, content_encoding=None,
+ content_language=None, content_disposition=None,
+ cache_control=None, content_md5=None, **kwargs):
+
+ self.content_type = content_type or kwargs.get('Content-Type')
+ self.content_encoding = content_encoding or kwargs.get('Content-Encoding')
+ self.content_language = content_language or kwargs.get('Content-Language')
+ self.content_md5 = content_md5 or kwargs.get('Content-MD5')
+ self.content_disposition = content_disposition or kwargs.get('Content-Disposition')
+ self.cache_control = cache_control or kwargs.get('Cache-Control')
+
+ @classmethod
+ def _from_generated(cls, generated):
+ settings = cls()
+ settings.content_type = generated.properties.content_type or None
+ settings.content_encoding = generated.properties.content_encoding or None
+ settings.content_language = generated.properties.content_language or None
+ settings.content_md5 = generated.properties.content_md5 or None
+ settings.content_disposition = generated.properties.content_disposition or None
+ settings.cache_control = generated.properties.cache_control or None
+ return settings
+
+
+class CopyProperties(DictMixin):
+ """Blob Copy Properties.
+
+ These properties will be `None` if this blob has never been the destination
+ in a Copy Blob operation, or if this blob has been modified after a concluded
+ Copy Blob operation, for example, using Set Blob Properties, Upload Blob, or Commit Block List.
+
+ :ivar str id:
+ String identifier for the last attempted Copy Blob operation where this blob
+ was the destination blob.
+ :ivar str source:
+ URL up to 2 KB in length that specifies the source blob used in the last attempted
+ Copy Blob operation where this blob was the destination blob.
+ :ivar str status:
+ State of the copy operation identified by Copy ID, with these values:
+ success:
+ Copy completed successfully.
+ pending:
+ Copy is in progress. Check copy_status_description if intermittent,
+ non-fatal errors impede copy progress but don't cause failure.
+ aborted:
+ Copy was ended by Abort Copy Blob.
+ failed:
+ Copy failed. See copy_status_description for failure details.
+ :ivar str progress:
+ Contains the number of bytes copied and the total bytes in the source in the last
+ attempted Copy Blob operation where this blob was the destination blob. Can show
+ between 0 and Content-Length bytes copied.
+ :ivar ~datetime.datetime completion_time:
+ Conclusion time of the last attempted Copy Blob operation where this blob was the
+ destination blob. This value can specify the time of a completed, aborted, or
+ failed copy attempt.
+ :ivar str status_description:
+ Only appears when x-ms-copy-status is failed or pending. Describes cause of fatal
+ or non-fatal copy operation failure.
+ :ivar bool incremental_copy:
+ Copies the snapshot of the source page blob to a destination page blob.
+ The snapshot is copied such that only the differential changes between
+ the previously copied snapshot are transferred to the destination
+ :ivar ~datetime.datetime destination_snapshot:
+ Included if the blob is incremental copy blob or incremental copy snapshot,
+ if x-ms-copy-status is success. Snapshot time of the last successful
+ incremental copy snapshot for this blob.
+ """
+
+ def __init__(self, **kwargs):
+ self.id = kwargs.get('x-ms-copy-id')
+ self.source = kwargs.get('x-ms-copy-source')
+ self.status = get_enum_value(kwargs.get('x-ms-copy-status'))
+ self.progress = kwargs.get('x-ms-copy-progress')
+ self.completion_time = kwargs.get('x-ms-copy-completion_time')
+ self.status_description = kwargs.get('x-ms-copy-status-description')
+ self.incremental_copy = kwargs.get('x-ms-incremental-copy')
+ self.destination_snapshot = kwargs.get('x-ms-copy-destination-snapshot')
+
+ @classmethod
+ def _from_generated(cls, generated):
+ copy = cls()
+ copy.id = generated.properties.copy_id or None
+ copy.status = get_enum_value(generated.properties.copy_status) or None
+ copy.source = generated.properties.copy_source or None
+ copy.progress = generated.properties.copy_progress or None
+ copy.completion_time = generated.properties.copy_completion_time or None
+ copy.status_description = generated.properties.copy_status_description or None
+ copy.incremental_copy = generated.properties.incremental_copy or None
+ copy.destination_snapshot = generated.properties.destination_snapshot or None
+ return copy
+
+
+class BlobBlock(DictMixin):
+ """BlockBlob Block class.
+
+ :param str block_id:
+ Block id.
+ :param str state:
+ Block state. Possible values: committed|uncommitted
+ :ivar int size:
+ Block size in bytes.
+ """
+
+ def __init__(self, block_id, state=BlockState.Latest):
+ self.id = block_id
+ self.state = state
+ self.size = None
+
+ @classmethod
+ def _from_generated(cls, generated):
+ try:
+ decoded_bytes = decode_base64_to_bytes(generated.name)
+ block_id = decoded_bytes.decode('utf-8')
+ # this is to fix a bug. When large blocks are uploaded through upload_blob the block id isn't base64 encoded
+ # while service expected block id is base64 encoded, so when we get block_id if we cannot base64 decode, it
+ # means we didn't base64 encode it when stage the block, we want to use the returned block_id directly.
+ except UnicodeDecodeError:
+ block_id = generated.name
+ block = cls(block_id)
+ block.size = generated.size
+ return block
+
+
+class PageRange(DictMixin):
+ """Page Range for page blob.
+
+ :param int start:
+ Start of page range in bytes.
+ :param int end:
+ End of page range in bytes.
+ """
+
+ def __init__(self, start=None, end=None):
+ self.start = start
+ self.end = end
+
+
+class AccessPolicy(GenAccessPolicy):
+ """Access Policy class used by the set and get access policy methods in each service.
+
+ A stored access policy can specify the start time, expiry time, and
+ permissions for the Shared Access Signatures with which it's associated.
+ Depending on how you want to control access to your resource, you can
+ specify all of these parameters within the stored access policy, and omit
+ them from the URL for the Shared Access Signature. Doing so permits you to
+ modify the associated signature's behavior at any time, as well as to revoke
+ it. Or you can specify one or more of the access policy parameters within
+ the stored access policy, and the others on the URL. Finally, you can
+ specify all of the parameters on the URL. In this case, you can use the
+ stored access policy to revoke the signature, but not to modify its behavior.
+
+ Together the Shared Access Signature and the stored access policy must
+ include all fields required to authenticate the signature. If any required
+ fields are missing, the request will fail. Likewise, if a field is specified
+ both in the Shared Access Signature URL and in the stored access policy, the
+ request will fail with status code 400 (Bad Request).
+
+ :param permission:
+ The permissions associated with the shared access signature. The
+ user is restricted to operations allowed by the permissions.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has been
+ specified in an associated stored access policy.
+ :type permission: str or ~azure.storage.blob.ContainerSasPermissions
+ :param expiry:
+ The time at which the shared access signature becomes invalid.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has
+ been specified in an associated stored access policy. Azure will always
+ convert values to UTC. If a date is passed in without timezone info, it
+ is assumed to be UTC.
+ :type expiry: ~datetime.datetime or str
+ :param start:
+ The time at which the shared access signature becomes valid. If
+ omitted, start time for this call is assumed to be the time when the
+ storage service receives the request. Azure will always convert values
+ to UTC. If a date is passed in without timezone info, it is assumed to
+ be UTC.
+ :type start: ~datetime.datetime or str
+ """
+ def __init__(self, permission=None, expiry=None, start=None):
+ self.start = start
+ self.expiry = expiry
+ self.permission = permission
+
+
+class ContainerSasPermissions(object):
+ """ContainerSasPermissions class to be used with the
+ :func:`~azure.storage.blob.generate_container_sas` function and
+ for the AccessPolicies used with
+ :func:`~azure.storage.blob.ContainerClient.set_container_access_policy`.
+
+ :param bool read:
+ Read the content, properties, metadata or block list of any blob in the
+ container. Use any blob in the container as the source of a copy operation.
+ :param bool write:
+ For any blob in the container, create or write content, properties,
+ metadata, or block list. Snapshot or lease the blob. Resize the blob
+ (page blob only). Use the blob as the destination of a copy operation
+ within the same account. Note: You cannot grant permissions to read or
+ write container properties or metadata, nor to lease a container, with
+ a container SAS. Use an account SAS instead.
+ :param bool delete:
+ Delete any blob in the container. Note: You cannot grant permissions to
+ delete a container with a container SAS. Use an account SAS instead.
+ :param bool delete_previous_version:
+ Delete the previous blob version for the versioning enabled storage account.
+ :param bool list:
+ List blobs in the container.
+ :param bool tag:
+ Set or get tags on the blobs in the container.
+ :keyword bool add:
+ Add a block to an append blob.
+ :keyword bool create:
+ Write a new blob, snapshot a blob, or copy a blob to a new blob.
+ :keyword bool permanent_delete:
+ To enable permanent delete on the blob is permitted.
+ :keyword bool filter_by_tags:
+ To enable finding blobs by tags.
+ :keyword bool move:
+ Move a blob or a directory and its contents to a new location.
+ :keyword bool execute:
+ Get the system properties and, if the hierarchical namespace is enabled for the storage account,
+ get the POSIX ACL of a blob.
+ :keyword bool set_immutability_policy:
+ To enable operations related to set/delete immutability policy.
+ To get immutability policy, you just need read permission.
+ """
+ def __init__(self, read=False, write=False, delete=False,
+ list=False, delete_previous_version=False, tag=False, **kwargs): # pylint: disable=redefined-builtin
+ self.read = read
+ self.add = kwargs.pop('add', False)
+ self.create = kwargs.pop('create', False)
+ self.write = write
+ self.delete = delete
+ self.delete_previous_version = delete_previous_version
+ self.permanent_delete = kwargs.pop('permanent_delete', False)
+ self.list = list
+ self.tag = tag
+ self.filter_by_tags = kwargs.pop('filter_by_tags', False)
+ self.move = kwargs.pop('move', False)
+ self.execute = kwargs.pop('execute', False)
+ self.set_immutability_policy = kwargs.pop('set_immutability_policy', False)
+ self._str = (('r' if self.read else '') +
+ ('a' if self.add else '') +
+ ('c' if self.create else '') +
+ ('w' if self.write else '') +
+ ('d' if self.delete else '') +
+ ('x' if self.delete_previous_version else '') +
+ ('y' if self.permanent_delete else '') +
+ ('l' if self.list else '') +
+ ('t' if self.tag else '') +
+ ('f' if self.filter_by_tags else '') +
+ ('m' if self.move else '') +
+ ('e' if self.execute else '') +
+ ('i' if self.set_immutability_policy else ''))
+
+ def __str__(self):
+ return self._str
+
+ @classmethod
+ def from_string(cls, permission):
+ """Create a ContainerSasPermissions from a string.
+
+ To specify read, write, delete, or list permissions you need only to
+ include the first letter of the word in the string. E.g. For read and
+ write permissions, you would provide a string "rw".
+
+ :param str permission: The string which dictates the read, write, delete,
+ and list permissions.
+ :return: A ContainerSasPermissions object
+ :rtype: ~azure.storage.blob.ContainerSasPermissions
+ """
+ p_read = 'r' in permission
+ p_add = 'a' in permission
+ p_create = 'c' in permission
+ p_write = 'w' in permission
+ p_delete = 'd' in permission
+ p_delete_previous_version = 'x' in permission
+ p_permanent_delete = 'y' in permission
+ p_list = 'l' in permission
+ p_tag = 't' in permission
+ p_filter_by_tags = 'f' in permission
+ p_move = 'm' in permission
+ p_execute = 'e' in permission
+ p_set_immutability_policy = 'i' in permission
+ parsed = cls(read=p_read, write=p_write, delete=p_delete, list=p_list,
+ delete_previous_version=p_delete_previous_version, tag=p_tag, add=p_add,
+ create=p_create, permanent_delete=p_permanent_delete, filter_by_tags=p_filter_by_tags,
+ move=p_move, execute=p_execute, set_immutability_policy=p_set_immutability_policy)
+
+ return parsed
+
+
+class BlobSasPermissions(object):
+ """BlobSasPermissions class to be used with the
+ :func:`~azure.storage.blob.generate_blob_sas` function.
+
+ :param bool read:
+ Read the content, properties, metadata and block list. Use the blob as
+ the source of a copy operation.
+ :param bool add:
+ Add a block to an append blob.
+ :param bool create:
+ Write a new blob, snapshot a blob, or copy a blob to a new blob.
+ :param bool write:
+ Create or write content, properties, metadata, or block list. Snapshot
+ or lease the blob. Resize the blob (page blob only). Use the blob as the
+ destination of a copy operation within the same account.
+ :param bool delete:
+ Delete the blob.
+ :param bool delete_previous_version:
+ Delete the previous blob version for the versioning enabled storage account.
+ :param bool tag:
+ Set or get tags on the blob.
+ :keyword bool permanent_delete:
+ To enable permanent delete on the blob is permitted.
+ :keyword bool move:
+ Move a blob or a directory and its contents to a new location.
+ :keyword bool execute:
+ Get the system properties and, if the hierarchical namespace is enabled for the storage account,
+ get the POSIX ACL of a blob.
+ :keyword bool set_immutability_policy:
+ To enable operations related to set/delete immutability policy.
+ To get immutability policy, you just need read permission.
+ """
+ def __init__(self, read=False, add=False, create=False, write=False,
+ delete=False, delete_previous_version=False, tag=False, **kwargs):
+ self.read = read
+ self.add = add
+ self.create = create
+ self.write = write
+ self.delete = delete
+ self.delete_previous_version = delete_previous_version
+ self.permanent_delete = kwargs.pop('permanent_delete', False)
+ self.tag = tag
+ self.move = kwargs.pop('move', False)
+ self.execute = kwargs.pop('execute', False)
+ self.set_immutability_policy = kwargs.pop('set_immutability_policy', False)
+ self._str = (('r' if self.read else '') +
+ ('a' if self.add else '') +
+ ('c' if self.create else '') +
+ ('w' if self.write else '') +
+ ('d' if self.delete else '') +
+ ('x' if self.delete_previous_version else '') +
+ ('y' if self.permanent_delete else '') +
+ ('t' if self.tag else '') +
+ ('m' if self.move else '') +
+ ('e' if self.execute else '') +
+ ('i' if self.set_immutability_policy else ''))
+
+ def __str__(self):
+ return self._str
+
+ @classmethod
+ def from_string(cls, permission):
+ """Create a BlobSasPermissions from a string.
+
+ To specify read, add, create, write, or delete permissions you need only to
+ include the first letter of the word in the string. E.g. For read and
+ write permissions, you would provide a string "rw".
+
+ :param str permission: The string which dictates the read, add, create,
+ write, or delete permissions.
+ :return: A BlobSasPermissions object
+ :rtype: ~azure.storage.blob.BlobSasPermissions
+ """
+ p_read = 'r' in permission
+ p_add = 'a' in permission
+ p_create = 'c' in permission
+ p_write = 'w' in permission
+ p_delete = 'd' in permission
+ p_delete_previous_version = 'x' in permission
+ p_permanent_delete = 'y' in permission
+ p_tag = 't' in permission
+ p_move = 'm' in permission
+ p_execute = 'e' in permission
+ p_set_immutability_policy = 'i' in permission
+
+ parsed = cls(read=p_read, add=p_add, create=p_create, write=p_write, delete=p_delete,
+ delete_previous_version=p_delete_previous_version, tag=p_tag, permanent_delete=p_permanent_delete,
+ move=p_move, execute=p_execute, set_immutability_policy=p_set_immutability_policy)
+
+ return parsed
+
+
+class CustomerProvidedEncryptionKey(object):
+ """
+ All data in Azure Storage is encrypted at-rest using an account-level encryption key.
+ In versions 2018-06-17 and newer, you can manage the key used to encrypt blob contents
+ and application metadata per-blob by providing an AES-256 encryption key in requests to the storage service.
+
+ When you use a customer-provided key, Azure Storage does not manage or persist your key.
+ When writing data to a blob, the provided key is used to encrypt your data before writing it to disk.
+ A SHA-256 hash of the encryption key is written alongside the blob contents,
+ and is used to verify that all subsequent operations against the blob use the same encryption key.
+ This hash cannot be used to retrieve the encryption key or decrypt the contents of the blob.
+ When reading a blob, the provided key is used to decrypt your data after reading it from disk.
+ In both cases, the provided encryption key is securely discarded
+ as soon as the encryption or decryption process completes.
+
+ :param str key_value:
+ Base64-encoded AES-256 encryption key value.
+ :param str key_hash:
+ Base64-encoded SHA256 of the encryption key.
+ :ivar str algorithm:
+ Specifies the algorithm to use when encrypting data using the given key. Must be AES256.
+ """
+ def __init__(self, key_value, key_hash):
+ self.key_value = key_value
+ self.key_hash = key_hash
+ self.algorithm = 'AES256'
+
+
+class ContainerEncryptionScope(object):
+ """The default encryption scope configuration for a container.
+
+ This scope is used implicitly for all future writes within the container,
+ but can be overridden per blob operation.
+
+ .. versionadded:: 12.2.0
+
+ :param str default_encryption_scope:
+ Specifies the default encryption scope to set on the container and use for
+ all future writes.
+ :param bool prevent_encryption_scope_override:
+ If true, prevents any request from specifying a different encryption scope than the scope
+ set on the container. Default value is false.
+ """
+
+ def __init__(self, default_encryption_scope, **kwargs):
+ self.default_encryption_scope = default_encryption_scope
+ self.prevent_encryption_scope_override = kwargs.get('prevent_encryption_scope_override', False)
+
+ @classmethod
+ def _from_generated(cls, generated):
+ if generated.properties.default_encryption_scope:
+ scope = cls(
+ generated.properties.default_encryption_scope,
+ prevent_encryption_scope_override=generated.properties.prevent_encryption_scope_override or False
+ )
+ return scope
+ return None
+
+
+class DelimitedJsonDialect(DictMixin):
+ """Defines the input or output JSON serialization for a blob data query.
+
+ :keyword str delimiter: The line separator character, default value is '\n'
+ """
+
+ def __init__(self, **kwargs):
+ self.delimiter = kwargs.pop('delimiter', '\n')
+
+
+class DelimitedTextDialect(DictMixin):
+ """Defines the input or output delimited (CSV) serialization for a blob query request.
+
+ :keyword str delimiter:
+ Column separator, defaults to ','.
+ :keyword str quotechar:
+ Field quote, defaults to '"'.
+ :keyword str lineterminator:
+ Record separator, defaults to '\\\\n'.
+ :keyword str escapechar:
+ Escape char, defaults to empty.
+ :keyword bool has_header:
+ Whether the blob data includes headers in the first line. The default value is False, meaning that the
+ data will be returned inclusive of the first line. If set to True, the data will be returned exclusive
+ of the first line.
+ """
+ def __init__(self, **kwargs):
+ self.delimiter = kwargs.pop('delimiter', ',')
+ self.quotechar = kwargs.pop('quotechar', '"')
+ self.lineterminator = kwargs.pop('lineterminator', '\n')
+ self.escapechar = kwargs.pop('escapechar', "")
+ self.has_header = kwargs.pop('has_header', False)
+
+
+class ArrowDialect(ArrowField):
+ """field of an arrow schema.
+
+ All required parameters must be populated in order to send to Azure.
+
+ :param ~azure.storage.blob.ArrowType type: Arrow field type.
+ :keyword str name: The name of the field.
+ :keyword int precision: The precision of the field.
+ :keyword int scale: The scale of the field.
+ """
+ def __init__(self, type, **kwargs): # pylint: disable=redefined-builtin
+ super(ArrowDialect, self).__init__(type=type, **kwargs)
+
+
+class ArrowType(str, Enum):
+
+ INT64 = "int64"
+ BOOL = "bool"
+ TIMESTAMP_MS = "timestamp[ms]"
+ STRING = "string"
+ DOUBLE = "double"
+ DECIMAL = 'decimal'
+
+
+class ObjectReplicationPolicy(DictMixin):
+ """Policy id and rule ids applied to a blob.
+
+ :ivar str policy_id:
+ Policy id for the blob. A replication policy gets created (policy id) when creating a source/destination pair.
+ :ivar list(~azure.storage.blob.ObjectReplicationRule) rules:
+ Within each policy there may be multiple replication rules.
+ e.g. rule 1= src/container/.pdf to dst/container2/; rule2 = src/container1/.jpg to dst/container3
+ """
+
+ def __init__(self, **kwargs):
+ self.policy_id = kwargs.pop('policy_id', None)
+ self.rules = kwargs.pop('rules', None)
+
+
+class ObjectReplicationRule(DictMixin):
+ """Policy id and rule ids applied to a blob.
+
+ :ivar str rule_id:
+ Rule id.
+ :ivar str status:
+ The status of the rule. It could be "Complete" or "Failed"
+ """
+
+ def __init__(self, **kwargs):
+ self.rule_id = kwargs.pop('rule_id', None)
+ self.status = kwargs.pop('status', None)
+
+
+class BlobQueryError(object):
+ """The error happened during quick query operation.
+
+ :ivar str error:
+ The name of the error.
+ :ivar bool is_fatal:
+ If true, this error prevents further query processing. More result data may be returned,
+ but there is no guarantee that all of the original data will be processed.
+ If false, this error does not prevent further query processing.
+ :ivar str description:
+ A description of the error.
+ :ivar int position:
+ The blob offset at which the error occurred.
+ """
+ def __init__(self, error=None, is_fatal=False, description=None, position=None):
+ self.error = error
+ self.is_fatal = is_fatal
+ self.description = description
+ self.position = position
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_quick_query_helper.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_quick_query_helper.py
new file mode 100644
index 00000000000..3164337308c
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_quick_query_helper.py
@@ -0,0 +1,195 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+from io import BytesIO
+from typing import Union, Iterable, IO # pylint: disable=unused-import
+
+from ._shared.avro.datafile import DataFileReader
+from ._shared.avro.avro_io import DatumReader
+
+
+class BlobQueryReader(object): # pylint: disable=too-many-instance-attributes
+ """A streaming object to read query results.
+
+ :ivar str name:
+ The name of the blob being quered.
+ :ivar str container:
+ The name of the container where the blob is.
+ :ivar dict response_headers:
+ The response_headers of the quick query request.
+ :ivar bytes record_delimiter:
+ The delimiter used to separate lines, or records with the data. The `records`
+ method will return these lines via a generator.
+ """
+
+ def __init__(
+ self,
+ name=None,
+ container=None,
+ errors=None,
+ record_delimiter='\n',
+ encoding=None,
+ headers=None,
+ response=None,
+ error_cls=None,
+ ):
+ self.name = name
+ self.container = container
+ self.response_headers = headers
+ self.record_delimiter = record_delimiter
+ self._size = 0
+ self._bytes_processed = 0
+ self._errors = errors
+ self._encoding = encoding
+ self._parsed_results = DataFileReader(QuickQueryStreamer(response), DatumReader())
+ self._first_result = self._process_record(next(self._parsed_results))
+ self._error_cls = error_cls
+
+ def __len__(self):
+ return self._size
+
+ def _process_record(self, result):
+ self._size = result.get('totalBytes', self._size)
+ self._bytes_processed = result.get('bytesScanned', self._bytes_processed)
+ if 'data' in result:
+ return result.get('data')
+ if 'fatal' in result:
+ error = self._error_cls(
+ error=result['name'],
+ is_fatal=result['fatal'],
+ description=result['description'],
+ position=result['position']
+ )
+ if self._errors:
+ self._errors(error)
+ return None
+
+ def _iter_stream(self):
+ if self._first_result is not None:
+ yield self._first_result
+ for next_result in self._parsed_results:
+ processed_result = self._process_record(next_result)
+ if processed_result is not None:
+ yield processed_result
+
+ def readall(self):
+ # type: () -> Union[bytes, str]
+ """Return all query results.
+
+ This operation is blocking until all data is downloaded.
+ If encoding has been configured - this will be used to decode individual
+ records are they are received.
+
+ :rtype: Union[bytes, str]
+ """
+ stream = BytesIO()
+ self.readinto(stream)
+ data = stream.getvalue()
+ if self._encoding:
+ return data.decode(self._encoding)
+ return data
+
+ def readinto(self, stream):
+ # type: (IO) -> None
+ """Download the query result to a stream.
+
+ :param stream:
+ The stream to download to. This can be an open file-handle,
+ or any writable stream.
+ :returns: None
+ """
+ for record in self._iter_stream():
+ stream.write(record)
+
+ def records(self):
+ # type: () -> Iterable[Union[bytes, str]]
+ """Returns a record generator for the query result.
+
+ Records will be returned line by line.
+ If encoding has been configured - this will be used to decode individual
+ records are they are received.
+
+ :rtype: Iterable[Union[bytes, str]]
+ """
+ delimiter = self.record_delimiter.encode('utf-8')
+ for record_chunk in self._iter_stream():
+ for record in record_chunk.split(delimiter):
+ if self._encoding:
+ yield record.decode(self._encoding)
+ else:
+ yield record
+
+
+class QuickQueryStreamer(object):
+ """
+ File-like streaming iterator.
+ """
+
+ def __init__(self, generator):
+ self.generator = generator
+ self.iterator = iter(generator)
+ self._buf = b""
+ self._point = 0
+ self._download_offset = 0
+ self._buf_start = 0
+ self.file_length = None
+
+ def __len__(self):
+ return self.file_length
+
+ def __iter__(self):
+ return self.iterator
+
+ @staticmethod
+ def seekable():
+ return True
+
+ def __next__(self):
+ next_part = next(self.iterator)
+ self._download_offset += len(next_part)
+ return next_part
+
+ next = __next__ # Python 2 compatibility.
+
+ def tell(self):
+ return self._point
+
+ def seek(self, offset, whence=0):
+ if whence == 0:
+ self._point = offset
+ elif whence == 1:
+ self._point += offset
+ else:
+ raise ValueError("whence must be 0, or 1")
+ if self._point < 0:
+ self._point = 0 # XXX is this right?
+
+ def read(self, size):
+ try:
+ # keep reading from the generator until the buffer of this stream has enough data to read
+ while self._point + size > self._download_offset:
+ self._buf += self.__next__()
+ except StopIteration:
+ self.file_length = self._download_offset
+
+ start_point = self._point
+
+ # EOF
+ self._point = min(self._point + size, self._download_offset)
+
+ relative_start = start_point - self._buf_start
+ if relative_start < 0:
+ raise ValueError("Buffer has dumped too much data")
+ relative_end = relative_start + size
+ data = self._buf[relative_start: relative_end]
+
+ # dump the extra data in buffer
+ # buffer start--------------------16bytes----current read position
+ dumped_size = max(relative_end - 16 - relative_start, 0)
+ self._buf_start += dumped_size
+ self._buf = self._buf[dumped_size:]
+
+ return data
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_serialize.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_serialize.py
new file mode 100644
index 00000000000..b6399c0cb7d
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_serialize.py
@@ -0,0 +1,215 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=no-self-use
+from typing import ( # pylint: disable=unused-import
+ Any, Dict, Optional, Tuple, Union,
+ TYPE_CHECKING)
+
+try:
+ from urllib.parse import quote
+except ImportError:
+ from urllib2 import quote # type: ignore
+
+from azure.core import MatchConditions
+
+from ._models import (
+ ContainerEncryptionScope,
+ DelimitedJsonDialect)
+from ._generated.models import (
+ ModifiedAccessConditions,
+ SourceModifiedAccessConditions,
+ CpkScopeInfo,
+ ContainerCpkScopeInfo,
+ QueryFormat,
+ QuerySerialization,
+ DelimitedTextConfiguration,
+ JsonTextConfiguration,
+ ArrowConfiguration,
+ QueryFormatType,
+ BlobTag,
+ BlobTags, LeaseAccessConditions
+)
+
+if TYPE_CHECKING:
+ from ._lease import BlobLeaseClient
+
+
+_SUPPORTED_API_VERSIONS = [
+ '2019-02-02',
+ '2019-07-07',
+ '2019-10-10',
+ '2019-12-12',
+ '2020-02-10',
+ '2020-04-08',
+ '2020-06-12',
+ '2020-08-04',
+ '2020-10-02',
+ '2020-12-06',
+ '2021-02-12',
+ '2021-04-10'
+]
+
+
+def _get_match_headers(kwargs, match_param, etag_param):
+ # type: (Dict[str, Any], str, str) -> Tuple(Dict[str, Any], Optional[str], Optional[str])
+ if_match = None
+ if_none_match = None
+ match_condition = kwargs.pop(match_param, None)
+ if match_condition == MatchConditions.IfNotModified:
+ if_match = kwargs.pop(etag_param, None)
+ if not if_match:
+ raise ValueError("'{}' specified without '{}'.".format(match_param, etag_param))
+ elif match_condition == MatchConditions.IfPresent:
+ if_match = '*'
+ elif match_condition == MatchConditions.IfModified:
+ if_none_match = kwargs.pop(etag_param, None)
+ if not if_none_match:
+ raise ValueError("'{}' specified without '{}'.".format(match_param, etag_param))
+ elif match_condition == MatchConditions.IfMissing:
+ if_none_match = '*'
+ elif match_condition is None:
+ if kwargs.get(etag_param):
+ raise ValueError("'{}' specified without '{}'.".format(etag_param, match_param))
+ else:
+ raise TypeError("Invalid match condition: {}".format(match_condition))
+ return if_match, if_none_match
+
+
+def get_access_conditions(lease):
+ # type: (Optional[Union[BlobLeaseClient, str]]) -> Union[LeaseAccessConditions, None]
+ try:
+ lease_id = lease.id # type: ignore
+ except AttributeError:
+ lease_id = lease # type: ignore
+ return LeaseAccessConditions(lease_id=lease_id) if lease_id else None
+
+
+def get_modify_conditions(kwargs):
+ # type: (Dict[str, Any]) -> ModifiedAccessConditions
+ if_match, if_none_match = _get_match_headers(kwargs, 'match_condition', 'etag')
+ return ModifiedAccessConditions(
+ if_modified_since=kwargs.pop('if_modified_since', None),
+ if_unmodified_since=kwargs.pop('if_unmodified_since', None),
+ if_match=if_match or kwargs.pop('if_match', None),
+ if_none_match=if_none_match or kwargs.pop('if_none_match', None),
+ if_tags=kwargs.pop('if_tags_match_condition', None)
+ )
+
+
+def get_source_conditions(kwargs):
+ # type: (Dict[str, Any]) -> SourceModifiedAccessConditions
+ if_match, if_none_match = _get_match_headers(kwargs, 'source_match_condition', 'source_etag')
+ return SourceModifiedAccessConditions(
+ source_if_modified_since=kwargs.pop('source_if_modified_since', None),
+ source_if_unmodified_since=kwargs.pop('source_if_unmodified_since', None),
+ source_if_match=if_match or kwargs.pop('source_if_match', None),
+ source_if_none_match=if_none_match or kwargs.pop('source_if_none_match', None),
+ source_if_tags=kwargs.pop('source_if_tags_match_condition', None)
+ )
+
+
+def get_cpk_scope_info(kwargs):
+ # type: (Dict[str, Any]) -> CpkScopeInfo
+ if 'encryption_scope' in kwargs:
+ return CpkScopeInfo(encryption_scope=kwargs.pop('encryption_scope'))
+ return None
+
+
+def get_container_cpk_scope_info(kwargs):
+ # type: (Dict[str, Any]) -> ContainerCpkScopeInfo
+ encryption_scope = kwargs.pop('container_encryption_scope', None)
+ if encryption_scope:
+ if isinstance(encryption_scope, ContainerEncryptionScope):
+ return ContainerCpkScopeInfo(
+ default_encryption_scope=encryption_scope.default_encryption_scope,
+ prevent_encryption_scope_override=encryption_scope.prevent_encryption_scope_override
+ )
+ if isinstance(encryption_scope, dict):
+ return ContainerCpkScopeInfo(
+ default_encryption_scope=encryption_scope['default_encryption_scope'],
+ prevent_encryption_scope_override=encryption_scope.get('prevent_encryption_scope_override')
+ )
+ raise TypeError("Container encryption scope must be dict or type ContainerEncryptionScope.")
+ return None
+
+
+def get_api_version(kwargs):
+ # type: (Dict[str, Any]) -> str
+ api_version = kwargs.get('api_version', None)
+ if api_version and api_version not in _SUPPORTED_API_VERSIONS:
+ versions = '\n'.join(_SUPPORTED_API_VERSIONS)
+ raise ValueError("Unsupported API version '{}'. Please select from:\n{}".format(api_version, versions))
+ return api_version or _SUPPORTED_API_VERSIONS[-1]
+
+
+def serialize_blob_tags_header(tags=None):
+ # type: (Optional[Dict[str, str]]) -> str
+ if tags is None:
+ return None
+
+ components = list()
+ if tags:
+ for key, value in tags.items():
+ components.append(quote(key, safe='.-'))
+ components.append('=')
+ components.append(quote(value, safe='.-'))
+ components.append('&')
+
+ if components:
+ del components[-1]
+
+ return ''.join(components)
+
+
+def serialize_blob_tags(tags=None):
+ # type: (Optional[Dict[str, str]]) -> Union[BlobTags, None]
+ tag_list = list()
+ if tags:
+ tag_list = [BlobTag(key=k, value=v) for k, v in tags.items()]
+ return BlobTags(blob_tag_set=tag_list)
+
+
+def serialize_query_format(formater):
+ if formater == "ParquetDialect":
+ qq_format = QueryFormat(
+ type=QueryFormatType.PARQUET,
+ parquet_text_configuration=' '
+ )
+ elif isinstance(formater, DelimitedJsonDialect):
+ serialization_settings = JsonTextConfiguration(
+ record_separator=formater.delimiter
+ )
+ qq_format = QueryFormat(
+ type=QueryFormatType.json,
+ json_text_configuration=serialization_settings)
+ elif hasattr(formater, 'quotechar'): # This supports a csv.Dialect as well
+ try:
+ headers = formater.has_header
+ except AttributeError:
+ headers = False
+ serialization_settings = DelimitedTextConfiguration(
+ column_separator=formater.delimiter,
+ field_quote=formater.quotechar,
+ record_separator=formater.lineterminator,
+ escape_char=formater.escapechar,
+ headers_present=headers
+ )
+ qq_format = QueryFormat(
+ type=QueryFormatType.delimited,
+ delimited_text_configuration=serialization_settings
+ )
+ elif isinstance(formater, list):
+ serialization_settings = ArrowConfiguration(
+ schema=formater
+ )
+ qq_format = QueryFormat(
+ type=QueryFormatType.arrow,
+ arrow_configuration=serialization_settings)
+ elif not formater:
+ return None
+ else:
+ raise TypeError("Format must be DelimitedTextDialect or DelimitedJsonDialect or ParquetDialect.")
+ return QuerySerialization(format=qq_format)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/__init__.py
new file mode 100644
index 00000000000..160f8822382
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/__init__.py
@@ -0,0 +1,56 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import base64
+import hashlib
+import hmac
+
+try:
+ from urllib.parse import quote, unquote
+except ImportError:
+ from urllib2 import quote, unquote # type: ignore
+
+import six
+
+
+def url_quote(url):
+ return quote(url)
+
+
+def url_unquote(url):
+ return unquote(url)
+
+
+def encode_base64(data):
+ if isinstance(data, six.text_type):
+ data = data.encode('utf-8')
+ encoded = base64.b64encode(data)
+ return encoded.decode('utf-8')
+
+
+def decode_base64_to_bytes(data):
+ if isinstance(data, six.text_type):
+ data = data.encode('utf-8')
+ return base64.b64decode(data)
+
+
+def decode_base64_to_text(data):
+ decoded_bytes = decode_base64_to_bytes(data)
+ return decoded_bytes.decode('utf-8')
+
+
+def sign_string(key, string_to_sign, key_is_base64=True):
+ if key_is_base64:
+ key = decode_base64_to_bytes(key)
+ else:
+ if isinstance(key, six.text_type):
+ key = key.encode('utf-8')
+ if isinstance(string_to_sign, six.text_type):
+ string_to_sign = string_to_sign.encode('utf-8')
+ signed_hmac_sha256 = hmac.HMAC(key, string_to_sign, hashlib.sha256)
+ digest = signed_hmac_sha256.digest()
+ encoded_digest = encode_base64(digest)
+ return encoded_digest
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/authentication.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/authentication.py
new file mode 100644
index 00000000000..adf64c7485b
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/authentication.py
@@ -0,0 +1,178 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import logging
+import re
+import sys
+
+try:
+ from urllib.parse import urlparse, unquote
+except ImportError:
+ from urlparse import urlparse # type: ignore
+ from urllib2 import unquote # type: ignore
+
+try:
+ from yarl import URL
+except ImportError:
+ pass
+
+try:
+ from azure.core.pipeline.transport import AioHttpTransport
+except ImportError:
+ AioHttpTransport = None
+
+from azure.core.exceptions import ClientAuthenticationError
+from azure.core.pipeline.policies import SansIOHTTPPolicy
+
+from . import sign_string
+
+
+logger = logging.getLogger(__name__)
+
+
+
+# wraps a given exception with the desired exception type
+def _wrap_exception(ex, desired_type):
+ msg = ""
+ if ex.args:
+ msg = ex.args[0]
+ if sys.version_info >= (3,):
+ # Automatic chaining in Python 3 means we keep the trace
+ return desired_type(msg)
+ # There isn't a good solution in 2 for keeping the stack trace
+ # in general, or that will not result in an error in 3
+ # However, we can keep the previous error type and message
+ # TODO: In the future we will log the trace
+ return desired_type('{}: {}'.format(ex.__class__.__name__, msg))
+
+
+class AzureSigningError(ClientAuthenticationError):
+ """
+ Represents a fatal error when attempting to sign a request.
+ In general, the cause of this exception is user error. For example, the given account key is not valid.
+ Please visit https://docs.microsoft.com/en-us/azure/storage/common/storage-create-storage-account for more info.
+ """
+
+
+# pylint: disable=no-self-use
+class SharedKeyCredentialPolicy(SansIOHTTPPolicy):
+
+ def __init__(self, account_name, account_key):
+ self.account_name = account_name
+ self.account_key = account_key
+ super(SharedKeyCredentialPolicy, self).__init__()
+
+ @staticmethod
+ def _get_headers(request, headers_to_sign):
+ headers = dict((name.lower(), value) for name, value in request.http_request.headers.items() if value)
+ if 'content-length' in headers and headers['content-length'] == '0':
+ del headers['content-length']
+ return '\n'.join(headers.get(x, '') for x in headers_to_sign) + '\n'
+
+ @staticmethod
+ def _get_verb(request):
+ return request.http_request.method + '\n'
+
+ def _get_canonicalized_resource(self, request):
+ uri_path = urlparse(request.http_request.url).path
+ try:
+ if isinstance(request.context.transport, AioHttpTransport) or \
+ isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport) or \
+ isinstance(getattr(getattr(request.context.transport, "_transport", None), "_transport", None),
+ AioHttpTransport):
+ uri_path = URL(uri_path)
+ return '/' + self.account_name + str(uri_path)
+ except TypeError:
+ pass
+ return '/' + self.account_name + uri_path
+
+ @staticmethod
+ def _get_canonicalized_headers(request):
+ string_to_sign = ''
+ x_ms_headers = []
+ for name, value in request.http_request.headers.items():
+ if name.startswith('x-ms-'):
+ x_ms_headers.append((name.lower(), value))
+ x_ms_headers.sort()
+ for name, value in x_ms_headers:
+ if value is not None:
+ string_to_sign += ''.join([name, ':', value, '\n'])
+ return string_to_sign
+
+ @staticmethod
+ def _get_canonicalized_resource_query(request):
+ sorted_queries = list(request.http_request.query.items())
+ sorted_queries.sort()
+
+ string_to_sign = ''
+ for name, value in sorted_queries:
+ if value is not None:
+ string_to_sign += '\n' + name.lower() + ':' + unquote(value)
+
+ return string_to_sign
+
+ def _add_authorization_header(self, request, string_to_sign):
+ try:
+ signature = sign_string(self.account_key, string_to_sign)
+ auth_string = 'SharedKey ' + self.account_name + ':' + signature
+ request.http_request.headers['Authorization'] = auth_string
+ except Exception as ex:
+ # Wrap any error that occurred as signing error
+ # Doing so will clarify/locate the source of problem
+ raise _wrap_exception(ex, AzureSigningError)
+
+ def on_request(self, request):
+ string_to_sign = \
+ self._get_verb(request) + \
+ self._get_headers(
+ request,
+ [
+ 'content-encoding', 'content-language', 'content-length',
+ 'content-md5', 'content-type', 'date', 'if-modified-since',
+ 'if-match', 'if-none-match', 'if-unmodified-since', 'byte_range'
+ ]
+ ) + \
+ self._get_canonicalized_headers(request) + \
+ self._get_canonicalized_resource(request) + \
+ self._get_canonicalized_resource_query(request)
+
+ self._add_authorization_header(request, string_to_sign)
+ #logger.debug("String_to_sign=%s", string_to_sign)
+
+
+class StorageHttpChallenge(object):
+ def __init__(self, challenge):
+ """ Parses an HTTP WWW-Authentication Bearer challenge from the Storage service. """
+ if not challenge:
+ raise ValueError("Challenge cannot be empty")
+
+ self._parameters = {}
+ self.scheme, trimmed_challenge = challenge.strip().split(" ", 1)
+
+ # name=value pairs either comma or space separated with values possibly being
+ # enclosed in quotes
+ for item in re.split('[, ]', trimmed_challenge):
+ comps = item.split("=")
+ if len(comps) == 2:
+ key = comps[0].strip(' "')
+ value = comps[1].strip(' "')
+ if key:
+ self._parameters[key] = value
+
+ # Extract and verify required parameters
+ self.authorization_uri = self._parameters.get('authorization_uri')
+ if not self.authorization_uri:
+ raise ValueError("Authorization Uri not found")
+
+ self.resource_id = self._parameters.get('resource_id')
+ if not self.resource_id:
+ raise ValueError("Resource id not found")
+
+ uri_path = urlparse(self.authorization_uri).path.lstrip("/")
+ self.tenant_id = uri_path.split("/")[0]
+
+ def get_value(self, key):
+ return self._parameters.get(key)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/__init__.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/__init__.py
new file mode 100644
index 00000000000..5b396cd202e
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/__init__.py
@@ -0,0 +1,5 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/avro_io.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/avro_io.py
new file mode 100644
index 00000000000..93a5c134849
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/avro_io.py
@@ -0,0 +1,464 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+"""Input/output utilities.
+
+Includes:
+ - i/o-specific constants
+ - i/o-specific exceptions
+ - schema validation
+ - leaf value encoding and decoding
+ - datum reader/writer stuff (?)
+
+Also includes a generic representation for data, which uses the
+following mapping:
+ - Schema records are implemented as dict.
+ - Schema arrays are implemented as list.
+ - Schema maps are implemented as dict.
+ - Schema strings are implemented as unicode.
+ - Schema bytes are implemented as str.
+ - Schema ints are implemented as int.
+ - Schema longs are implemented as long.
+ - Schema floats are implemented as float.
+ - Schema doubles are implemented as float.
+ - Schema booleans are implemented as bool.
+"""
+
+import json
+import logging
+import struct
+import sys
+
+from ..avro import schema
+
+PY3 = sys.version_info[0] == 3
+
+logger = logging.getLogger(__name__)
+
+# ------------------------------------------------------------------------------
+# Constants
+
+STRUCT_FLOAT = struct.Struct('= 0), n
+ input_bytes = self.reader.read(n)
+ if n > 0 and not input_bytes:
+ raise StopIteration
+ assert (len(input_bytes) == n), input_bytes
+ return input_bytes
+
+ @staticmethod
+ def read_null():
+ """
+ null is written as zero bytes
+ """
+ return None
+
+ def read_boolean(self):
+ """
+ a boolean is written as a single byte
+ whose value is either 0 (false) or 1 (true).
+ """
+ b = ord(self.read(1))
+ if b == 1:
+ return True
+ if b == 0:
+ return False
+ fail_msg = "Invalid value for boolean: %s" % b
+ raise schema.AvroException(fail_msg)
+
+ def read_int(self):
+ """
+ int and long values are written using variable-length, zig-zag coding.
+ """
+ return self.read_long()
+
+ def read_long(self):
+ """
+ int and long values are written using variable-length, zig-zag coding.
+ """
+ b = ord(self.read(1))
+ n = b & 0x7F
+ shift = 7
+ while (b & 0x80) != 0:
+ b = ord(self.read(1))
+ n |= (b & 0x7F) << shift
+ shift += 7
+ datum = (n >> 1) ^ -(n & 1)
+ return datum
+
+ def read_float(self):
+ """
+ A float is written as 4 bytes.
+ The float is converted into a 32-bit integer using a method equivalent to
+ Java's floatToIntBits and then encoded in little-endian format.
+ """
+ return STRUCT_FLOAT.unpack(self.read(4))[0]
+
+ def read_double(self):
+ """
+ A double is written as 8 bytes.
+ The double is converted into a 64-bit integer using a method equivalent to
+ Java's doubleToLongBits and then encoded in little-endian format.
+ """
+ return STRUCT_DOUBLE.unpack(self.read(8))[0]
+
+ def read_bytes(self):
+ """
+ Bytes are encoded as a long followed by that many bytes of data.
+ """
+ nbytes = self.read_long()
+ assert (nbytes >= 0), nbytes
+ return self.read(nbytes)
+
+ def read_utf8(self):
+ """
+ A string is encoded as a long followed by
+ that many bytes of UTF-8 encoded character data.
+ """
+ input_bytes = self.read_bytes()
+ if PY3:
+ try:
+ return input_bytes.decode('utf-8')
+ except UnicodeDecodeError as exn:
+ logger.error('Invalid UTF-8 input bytes: %r', input_bytes)
+ raise exn
+ else:
+ # PY2
+ return unicode(input_bytes, "utf-8") # pylint: disable=undefined-variable
+
+ def skip_null(self):
+ pass
+
+ def skip_boolean(self):
+ self.skip(1)
+
+ def skip_int(self):
+ self.skip_long()
+
+ def skip_long(self):
+ b = ord(self.read(1))
+ while (b & 0x80) != 0:
+ b = ord(self.read(1))
+
+ def skip_float(self):
+ self.skip(4)
+
+ def skip_double(self):
+ self.skip(8)
+
+ def skip_bytes(self):
+ self.skip(self.read_long())
+
+ def skip_utf8(self):
+ self.skip_bytes()
+
+ def skip(self, n):
+ self.reader.seek(self.reader.tell() + n)
+
+
+# ------------------------------------------------------------------------------
+# DatumReader
+
+
+class DatumReader(object):
+ """Deserialize Avro-encoded data into a Python data structure."""
+
+ def __init__(self, writer_schema=None):
+ """
+ As defined in the Avro specification, we call the schema encoded
+ in the data the "writer's schema".
+ """
+ self._writer_schema = writer_schema
+
+ # read/write properties
+ def set_writer_schema(self, writer_schema):
+ self._writer_schema = writer_schema
+
+ writer_schema = property(lambda self: self._writer_schema,
+ set_writer_schema)
+
+ def read(self, decoder):
+ return self.read_data(self.writer_schema, decoder)
+
+ def read_data(self, writer_schema, decoder):
+ # function dispatch for reading data based on type of writer's schema
+ if writer_schema.type == 'null':
+ result = decoder.read_null()
+ elif writer_schema.type == 'boolean':
+ result = decoder.read_boolean()
+ elif writer_schema.type == 'string':
+ result = decoder.read_utf8()
+ elif writer_schema.type == 'int':
+ result = decoder.read_int()
+ elif writer_schema.type == 'long':
+ result = decoder.read_long()
+ elif writer_schema.type == 'float':
+ result = decoder.read_float()
+ elif writer_schema.type == 'double':
+ result = decoder.read_double()
+ elif writer_schema.type == 'bytes':
+ result = decoder.read_bytes()
+ elif writer_schema.type == 'fixed':
+ result = self.read_fixed(writer_schema, decoder)
+ elif writer_schema.type == 'enum':
+ result = self.read_enum(writer_schema, decoder)
+ elif writer_schema.type == 'array':
+ result = self.read_array(writer_schema, decoder)
+ elif writer_schema.type == 'map':
+ result = self.read_map(writer_schema, decoder)
+ elif writer_schema.type in ['union', 'error_union']:
+ result = self.read_union(writer_schema, decoder)
+ elif writer_schema.type in ['record', 'error', 'request']:
+ result = self.read_record(writer_schema, decoder)
+ else:
+ fail_msg = "Cannot read unknown schema type: %s" % writer_schema.type
+ raise schema.AvroException(fail_msg)
+ return result
+
+ def skip_data(self, writer_schema, decoder):
+ if writer_schema.type == 'null':
+ result = decoder.skip_null()
+ elif writer_schema.type == 'boolean':
+ result = decoder.skip_boolean()
+ elif writer_schema.type == 'string':
+ result = decoder.skip_utf8()
+ elif writer_schema.type == 'int':
+ result = decoder.skip_int()
+ elif writer_schema.type == 'long':
+ result = decoder.skip_long()
+ elif writer_schema.type == 'float':
+ result = decoder.skip_float()
+ elif writer_schema.type == 'double':
+ result = decoder.skip_double()
+ elif writer_schema.type == 'bytes':
+ result = decoder.skip_bytes()
+ elif writer_schema.type == 'fixed':
+ result = self.skip_fixed(writer_schema, decoder)
+ elif writer_schema.type == 'enum':
+ result = self.skip_enum(decoder)
+ elif writer_schema.type == 'array':
+ self.skip_array(writer_schema, decoder)
+ result = None
+ elif writer_schema.type == 'map':
+ self.skip_map(writer_schema, decoder)
+ result = None
+ elif writer_schema.type in ['union', 'error_union']:
+ result = self.skip_union(writer_schema, decoder)
+ elif writer_schema.type in ['record', 'error', 'request']:
+ self.skip_record(writer_schema, decoder)
+ result = None
+ else:
+ fail_msg = "Unknown schema type: %s" % writer_schema.type
+ raise schema.AvroException(fail_msg)
+ return result
+
+ @staticmethod
+ def read_fixed(writer_schema, decoder):
+ """
+ Fixed instances are encoded using the number of bytes declared
+ in the schema.
+ """
+ return decoder.read(writer_schema.size)
+
+ @staticmethod
+ def skip_fixed(writer_schema, decoder):
+ return decoder.skip(writer_schema.size)
+
+ @staticmethod
+ def read_enum(writer_schema, decoder):
+ """
+ An enum is encoded by a int, representing the zero-based position
+ of the symbol in the schema.
+ """
+ # read data
+ index_of_symbol = decoder.read_int()
+ if index_of_symbol >= len(writer_schema.symbols):
+ fail_msg = "Can't access enum index %d for enum with %d symbols" \
+ % (index_of_symbol, len(writer_schema.symbols))
+ raise SchemaResolutionException(fail_msg, writer_schema)
+ read_symbol = writer_schema.symbols[index_of_symbol]
+ return read_symbol
+
+ @staticmethod
+ def skip_enum(decoder):
+ return decoder.skip_int()
+
+ def read_array(self, writer_schema, decoder):
+ """
+ Arrays are encoded as a series of blocks.
+
+ Each block consists of a long count value,
+ followed by that many array items.
+ A block with count zero indicates the end of the array.
+ Each item is encoded per the array's item schema.
+
+ If a block's count is negative,
+ then the count is followed immediately by a long block size,
+ indicating the number of bytes in the block.
+ The actual count in this case
+ is the absolute value of the count written.
+ """
+ read_items = []
+ block_count = decoder.read_long()
+ while block_count != 0:
+ if block_count < 0:
+ block_count = -block_count
+ decoder.read_long()
+ for _ in range(block_count):
+ read_items.append(self.read_data(writer_schema.items, decoder))
+ block_count = decoder.read_long()
+ return read_items
+
+ def skip_array(self, writer_schema, decoder):
+ block_count = decoder.read_long()
+ while block_count != 0:
+ if block_count < 0:
+ block_size = decoder.read_long()
+ decoder.skip(block_size)
+ else:
+ for _ in range(block_count):
+ self.skip_data(writer_schema.items, decoder)
+ block_count = decoder.read_long()
+
+ def read_map(self, writer_schema, decoder):
+ """
+ Maps are encoded as a series of blocks.
+
+ Each block consists of a long count value,
+ followed by that many key/value pairs.
+ A block with count zero indicates the end of the map.
+ Each item is encoded per the map's value schema.
+
+ If a block's count is negative,
+ then the count is followed immediately by a long block size,
+ indicating the number of bytes in the block.
+ The actual count in this case
+ is the absolute value of the count written.
+ """
+ read_items = {}
+ block_count = decoder.read_long()
+ while block_count != 0:
+ if block_count < 0:
+ block_count = -block_count
+ decoder.read_long()
+ for _ in range(block_count):
+ key = decoder.read_utf8()
+ read_items[key] = self.read_data(writer_schema.values, decoder)
+ block_count = decoder.read_long()
+ return read_items
+
+ def skip_map(self, writer_schema, decoder):
+ block_count = decoder.read_long()
+ while block_count != 0:
+ if block_count < 0:
+ block_size = decoder.read_long()
+ decoder.skip(block_size)
+ else:
+ for _ in range(block_count):
+ decoder.skip_utf8()
+ self.skip_data(writer_schema.values, decoder)
+ block_count = decoder.read_long()
+
+ def read_union(self, writer_schema, decoder):
+ """
+ A union is encoded by first writing a long value indicating
+ the zero-based position within the union of the schema of its value.
+ The value is then encoded per the indicated schema within the union.
+ """
+ # schema resolution
+ index_of_schema = int(decoder.read_long())
+ if index_of_schema >= len(writer_schema.schemas):
+ fail_msg = "Can't access branch index %d for union with %d branches" \
+ % (index_of_schema, len(writer_schema.schemas))
+ raise SchemaResolutionException(fail_msg, writer_schema)
+ selected_writer_schema = writer_schema.schemas[index_of_schema]
+
+ # read data
+ return self.read_data(selected_writer_schema, decoder)
+
+ def skip_union(self, writer_schema, decoder):
+ index_of_schema = int(decoder.read_long())
+ if index_of_schema >= len(writer_schema.schemas):
+ fail_msg = "Can't access branch index %d for union with %d branches" \
+ % (index_of_schema, len(writer_schema.schemas))
+ raise SchemaResolutionException(fail_msg, writer_schema)
+ return self.skip_data(writer_schema.schemas[index_of_schema], decoder)
+
+ def read_record(self, writer_schema, decoder):
+ """
+ A record is encoded by encoding the values of its fields
+ in the order that they are declared. In other words, a record
+ is encoded as just the concatenation of the encodings of its fields.
+ Field values are encoded per their schema.
+
+ Schema Resolution:
+ * the ordering of fields may be different: fields are matched by name.
+ * schemas for fields with the same name in both records are resolved
+ recursively.
+ * if the writer's record contains a field with a name not present in the
+ reader's record, the writer's value for that field is ignored.
+ * if the reader's record schema has a field that contains a default value,
+ and writer's schema does not have a field with the same name, then the
+ reader should use the default value from its field.
+ * if the reader's record schema has a field with no default value, and
+ writer's schema does not have a field with the same name, then the
+ field's value is unset.
+ """
+ # schema resolution
+ read_record = {}
+ for field in writer_schema.fields:
+ field_val = self.read_data(field.type, decoder)
+ read_record[field.name] = field_val
+ return read_record
+
+ def skip_record(self, writer_schema, decoder):
+ for field in writer_schema.fields:
+ self.skip_data(field.type, decoder)
+
+
+# ------------------------------------------------------------------------------
+
+if __name__ == '__main__':
+ raise Exception('Not a standalone module')
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/avro_io_async.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/avro_io_async.py
new file mode 100644
index 00000000000..e9812163795
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/avro_io_async.py
@@ -0,0 +1,448 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+"""Input/output utilities.
+
+Includes:
+ - i/o-specific constants
+ - i/o-specific exceptions
+ - schema validation
+ - leaf value encoding and decoding
+ - datum reader/writer stuff (?)
+
+Also includes a generic representation for data, which uses the
+following mapping:
+ - Schema records are implemented as dict.
+ - Schema arrays are implemented as list.
+ - Schema maps are implemented as dict.
+ - Schema strings are implemented as unicode.
+ - Schema bytes are implemented as str.
+ - Schema ints are implemented as int.
+ - Schema longs are implemented as long.
+ - Schema floats are implemented as float.
+ - Schema doubles are implemented as float.
+ - Schema booleans are implemented as bool.
+"""
+
+import logging
+import sys
+
+from ..avro import schema
+
+from .avro_io import STRUCT_FLOAT, STRUCT_DOUBLE, SchemaResolutionException
+
+PY3 = sys.version_info[0] == 3
+
+logger = logging.getLogger(__name__)
+
+# ------------------------------------------------------------------------------
+# Decoder
+
+
+class AsyncBinaryDecoder(object):
+ """Read leaf values."""
+
+ def __init__(self, reader):
+ """
+ reader is a Python object on which we can call read, seek, and tell.
+ """
+ self._reader = reader
+
+ @property
+ def reader(self):
+ """Reports the reader used by this decoder."""
+ return self._reader
+
+ async def read(self, n):
+ """Read n bytes.
+
+ Args:
+ n: Number of bytes to read.
+ Returns:
+ The next n bytes from the input.
+ """
+ assert (n >= 0), n
+ input_bytes = await self.reader.read(n)
+ if n > 0 and not input_bytes:
+ raise StopAsyncIteration
+ assert (len(input_bytes) == n), input_bytes
+ return input_bytes
+
+ @staticmethod
+ def read_null():
+ """
+ null is written as zero bytes
+ """
+ return None
+
+ async def read_boolean(self):
+ """
+ a boolean is written as a single byte
+ whose value is either 0 (false) or 1 (true).
+ """
+ b = ord(await self.read(1))
+ if b == 1:
+ return True
+ if b == 0:
+ return False
+ fail_msg = "Invalid value for boolean: %s" % b
+ raise schema.AvroException(fail_msg)
+
+ async def read_int(self):
+ """
+ int and long values are written using variable-length, zig-zag coding.
+ """
+ return await self.read_long()
+
+ async def read_long(self):
+ """
+ int and long values are written using variable-length, zig-zag coding.
+ """
+ b = ord(await self.read(1))
+ n = b & 0x7F
+ shift = 7
+ while (b & 0x80) != 0:
+ b = ord(await self.read(1))
+ n |= (b & 0x7F) << shift
+ shift += 7
+ datum = (n >> 1) ^ -(n & 1)
+ return datum
+
+ async def read_float(self):
+ """
+ A float is written as 4 bytes.
+ The float is converted into a 32-bit integer using a method equivalent to
+ Java's floatToIntBits and then encoded in little-endian format.
+ """
+ return STRUCT_FLOAT.unpack(await self.read(4))[0]
+
+ async def read_double(self):
+ """
+ A double is written as 8 bytes.
+ The double is converted into a 64-bit integer using a method equivalent to
+ Java's doubleToLongBits and then encoded in little-endian format.
+ """
+ return STRUCT_DOUBLE.unpack(await self.read(8))[0]
+
+ async def read_bytes(self):
+ """
+ Bytes are encoded as a long followed by that many bytes of data.
+ """
+ nbytes = await self.read_long()
+ assert (nbytes >= 0), nbytes
+ return await self.read(nbytes)
+
+ async def read_utf8(self):
+ """
+ A string is encoded as a long followed by
+ that many bytes of UTF-8 encoded character data.
+ """
+ input_bytes = await self.read_bytes()
+ if PY3:
+ try:
+ return input_bytes.decode('utf-8')
+ except UnicodeDecodeError as exn:
+ logger.error('Invalid UTF-8 input bytes: %r', input_bytes)
+ raise exn
+ else:
+ # PY2
+ return unicode(input_bytes, "utf-8") # pylint: disable=undefined-variable
+
+ def skip_null(self):
+ pass
+
+ async def skip_boolean(self):
+ await self.skip(1)
+
+ async def skip_int(self):
+ await self.skip_long()
+
+ async def skip_long(self):
+ b = ord(await self.read(1))
+ while (b & 0x80) != 0:
+ b = ord(await self.read(1))
+
+ async def skip_float(self):
+ await self.skip(4)
+
+ async def skip_double(self):
+ await self.skip(8)
+
+ async def skip_bytes(self):
+ await self.skip(await self.read_long())
+
+ async def skip_utf8(self):
+ await self.skip_bytes()
+
+ async def skip(self, n):
+ await self.reader.seek(await self.reader.tell() + n)
+
+
+# ------------------------------------------------------------------------------
+# DatumReader
+
+
+class AsyncDatumReader(object):
+ """Deserialize Avro-encoded data into a Python data structure."""
+
+ def __init__(self, writer_schema=None):
+ """
+ As defined in the Avro specification, we call the schema encoded
+ in the data the "writer's schema", and the schema expected by the
+ reader the "reader's schema".
+ """
+ self._writer_schema = writer_schema
+
+ # read/write properties
+ def set_writer_schema(self, writer_schema):
+ self._writer_schema = writer_schema
+
+ writer_schema = property(lambda self: self._writer_schema,
+ set_writer_schema)
+
+ async def read(self, decoder):
+ return await self.read_data(self.writer_schema, decoder)
+
+ async def read_data(self, writer_schema, decoder):
+ # function dispatch for reading data based on type of writer's schema
+ if writer_schema.type == 'null':
+ result = decoder.read_null()
+ elif writer_schema.type == 'boolean':
+ result = await decoder.read_boolean()
+ elif writer_schema.type == 'string':
+ result = await decoder.read_utf8()
+ elif writer_schema.type == 'int':
+ result = await decoder.read_int()
+ elif writer_schema.type == 'long':
+ result = await decoder.read_long()
+ elif writer_schema.type == 'float':
+ result = await decoder.read_float()
+ elif writer_schema.type == 'double':
+ result = await decoder.read_double()
+ elif writer_schema.type == 'bytes':
+ result = await decoder.read_bytes()
+ elif writer_schema.type == 'fixed':
+ result = await self.read_fixed(writer_schema, decoder)
+ elif writer_schema.type == 'enum':
+ result = await self.read_enum(writer_schema, decoder)
+ elif writer_schema.type == 'array':
+ result = await self.read_array(writer_schema, decoder)
+ elif writer_schema.type == 'map':
+ result = await self.read_map(writer_schema, decoder)
+ elif writer_schema.type in ['union', 'error_union']:
+ result = await self.read_union(writer_schema, decoder)
+ elif writer_schema.type in ['record', 'error', 'request']:
+ result = await self.read_record(writer_schema, decoder)
+ else:
+ fail_msg = "Cannot read unknown schema type: %s" % writer_schema.type
+ raise schema.AvroException(fail_msg)
+ return result
+
+ async def skip_data(self, writer_schema, decoder):
+ if writer_schema.type == 'null':
+ result = decoder.skip_null()
+ elif writer_schema.type == 'boolean':
+ result = await decoder.skip_boolean()
+ elif writer_schema.type == 'string':
+ result = await decoder.skip_utf8()
+ elif writer_schema.type == 'int':
+ result = await decoder.skip_int()
+ elif writer_schema.type == 'long':
+ result = await decoder.skip_long()
+ elif writer_schema.type == 'float':
+ result = await decoder.skip_float()
+ elif writer_schema.type == 'double':
+ result = await decoder.skip_double()
+ elif writer_schema.type == 'bytes':
+ result = await decoder.skip_bytes()
+ elif writer_schema.type == 'fixed':
+ result = await self.skip_fixed(writer_schema, decoder)
+ elif writer_schema.type == 'enum':
+ result = await self.skip_enum(decoder)
+ elif writer_schema.type == 'array':
+ await self.skip_array(writer_schema, decoder)
+ result = None
+ elif writer_schema.type == 'map':
+ await self.skip_map(writer_schema, decoder)
+ result = None
+ elif writer_schema.type in ['union', 'error_union']:
+ result = await self.skip_union(writer_schema, decoder)
+ elif writer_schema.type in ['record', 'error', 'request']:
+ await self.skip_record(writer_schema, decoder)
+ result = None
+ else:
+ fail_msg = "Unknown schema type: %s" % writer_schema.type
+ raise schema.AvroException(fail_msg)
+ return result
+
+ @staticmethod
+ async def read_fixed(writer_schema, decoder):
+ """
+ Fixed instances are encoded using the number of bytes declared
+ in the schema.
+ """
+ return await decoder.read(writer_schema.size)
+
+ @staticmethod
+ async def skip_fixed(writer_schema, decoder):
+ return await decoder.skip(writer_schema.size)
+
+ @staticmethod
+ async def read_enum(writer_schema, decoder):
+ """
+ An enum is encoded by a int, representing the zero-based position
+ of the symbol in the schema.
+ """
+ # read data
+ index_of_symbol = await decoder.read_int()
+ if index_of_symbol >= len(writer_schema.symbols):
+ fail_msg = "Can't access enum index %d for enum with %d symbols" \
+ % (index_of_symbol, len(writer_schema.symbols))
+ raise SchemaResolutionException(fail_msg, writer_schema)
+ read_symbol = writer_schema.symbols[index_of_symbol]
+ return read_symbol
+
+ @staticmethod
+ async def skip_enum(decoder):
+ return await decoder.skip_int()
+
+ async def read_array(self, writer_schema, decoder):
+ """
+ Arrays are encoded as a series of blocks.
+
+ Each block consists of a long count value,
+ followed by that many array items.
+ A block with count zero indicates the end of the array.
+ Each item is encoded per the array's item schema.
+
+ If a block's count is negative,
+ then the count is followed immediately by a long block size,
+ indicating the number of bytes in the block.
+ The actual count in this case
+ is the absolute value of the count written.
+ """
+ read_items = []
+ block_count = await decoder.read_long()
+ while block_count != 0:
+ if block_count < 0:
+ block_count = -block_count
+ await decoder.read_long()
+ for _ in range(block_count):
+ read_items.append(await self.read_data(writer_schema.items, decoder))
+ block_count = await decoder.read_long()
+ return read_items
+
+ async def skip_array(self, writer_schema, decoder):
+ block_count = await decoder.read_long()
+ while block_count != 0:
+ if block_count < 0:
+ block_size = await decoder.read_long()
+ await decoder.skip(block_size)
+ else:
+ for _ in range(block_count):
+ await self.skip_data(writer_schema.items, decoder)
+ block_count = await decoder.read_long()
+
+ async def read_map(self, writer_schema, decoder):
+ """
+ Maps are encoded as a series of blocks.
+
+ Each block consists of a long count value,
+ followed by that many key/value pairs.
+ A block with count zero indicates the end of the map.
+ Each item is encoded per the map's value schema.
+
+ If a block's count is negative,
+ then the count is followed immediately by a long block size,
+ indicating the number of bytes in the block.
+ The actual count in this case
+ is the absolute value of the count written.
+ """
+ read_items = {}
+ block_count = await decoder.read_long()
+ while block_count != 0:
+ if block_count < 0:
+ block_count = -block_count
+ await decoder.read_long()
+ for _ in range(block_count):
+ key = await decoder.read_utf8()
+ read_items[key] = await self.read_data(writer_schema.values, decoder)
+ block_count = await decoder.read_long()
+ return read_items
+
+ async def skip_map(self, writer_schema, decoder):
+ block_count = await decoder.read_long()
+ while block_count != 0:
+ if block_count < 0:
+ block_size = await decoder.read_long()
+ await decoder.skip(block_size)
+ else:
+ for _ in range(block_count):
+ await decoder.skip_utf8()
+ await self.skip_data(writer_schema.values, decoder)
+ block_count = await decoder.read_long()
+
+ async def read_union(self, writer_schema, decoder):
+ """
+ A union is encoded by first writing a long value indicating
+ the zero-based position within the union of the schema of its value.
+ The value is then encoded per the indicated schema within the union.
+ """
+ # schema resolution
+ index_of_schema = int(await decoder.read_long())
+ if index_of_schema >= len(writer_schema.schemas):
+ fail_msg = "Can't access branch index %d for union with %d branches" \
+ % (index_of_schema, len(writer_schema.schemas))
+ raise SchemaResolutionException(fail_msg, writer_schema)
+ selected_writer_schema = writer_schema.schemas[index_of_schema]
+
+ # read data
+ return await self.read_data(selected_writer_schema, decoder)
+
+ async def skip_union(self, writer_schema, decoder):
+ index_of_schema = int(await decoder.read_long())
+ if index_of_schema >= len(writer_schema.schemas):
+ fail_msg = "Can't access branch index %d for union with %d branches" \
+ % (index_of_schema, len(writer_schema.schemas))
+ raise SchemaResolutionException(fail_msg, writer_schema)
+ return await self.skip_data(writer_schema.schemas[index_of_schema], decoder)
+
+ async def read_record(self, writer_schema, decoder):
+ """
+ A record is encoded by encoding the values of its fields
+ in the order that they are declared. In other words, a record
+ is encoded as just the concatenation of the encodings of its fields.
+ Field values are encoded per their schema.
+
+ Schema Resolution:
+ * the ordering of fields may be different: fields are matched by name.
+ * schemas for fields with the same name in both records are resolved
+ recursively.
+ * if the writer's record contains a field with a name not present in the
+ reader's record, the writer's value for that field is ignored.
+ * if the reader's record schema has a field that contains a default value,
+ and writer's schema does not have a field with the same name, then the
+ reader should use the default value from its field.
+ * if the reader's record schema has a field with no default value, and
+ writer's schema does not have a field with the same name, then the
+ field's value is unset.
+ """
+ # schema resolution
+ read_record = {}
+ for field in writer_schema.fields:
+ field_val = await self.read_data(field.type, decoder)
+ read_record[field.name] = field_val
+ return read_record
+
+ async def skip_record(self, writer_schema, decoder):
+ for field in writer_schema.fields:
+ await self.skip_data(field.type, decoder)
+
+
+# ------------------------------------------------------------------------------
+
+if __name__ == '__main__':
+ raise Exception('Not a standalone module')
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/datafile.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/datafile.py
new file mode 100644
index 00000000000..df06fe0cfe7
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/datafile.py
@@ -0,0 +1,266 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+"""Read/Write Avro File Object Containers."""
+
+import io
+import logging
+import sys
+import zlib
+
+from ..avro import avro_io
+from ..avro import schema
+
+PY3 = sys.version_info[0] == 3
+
+logger = logging.getLogger(__name__)
+
+# ------------------------------------------------------------------------------
+# Constants
+
+# Version of the container file:
+VERSION = 1
+
+if PY3:
+ MAGIC = b'Obj' + bytes([VERSION])
+ MAGIC_SIZE = len(MAGIC)
+else:
+ MAGIC = 'Obj' + chr(VERSION)
+ MAGIC_SIZE = len(MAGIC)
+
+# Size of the synchronization marker, in number of bytes:
+SYNC_SIZE = 16
+
+# Schema of the container header:
+META_SCHEMA = schema.parse("""
+{
+ "type": "record", "name": "org.apache.avro.file.Header",
+ "fields": [{
+ "name": "magic",
+ "type": {"type": "fixed", "name": "magic", "size": %(magic_size)d}
+ }, {
+ "name": "meta",
+ "type": {"type": "map", "values": "bytes"}
+ }, {
+ "name": "sync",
+ "type": {"type": "fixed", "name": "sync", "size": %(sync_size)d}
+ }]
+}
+""" % {
+ 'magic_size': MAGIC_SIZE,
+ 'sync_size': SYNC_SIZE,
+})
+
+# Codecs supported by container files:
+VALID_CODECS = frozenset(['null', 'deflate'])
+
+# Metadata key associated to the schema:
+SCHEMA_KEY = "avro.schema"
+
+
+# ------------------------------------------------------------------------------
+# Exceptions
+
+
+class DataFileException(schema.AvroException):
+ """Problem reading or writing file object containers."""
+
+# ------------------------------------------------------------------------------
+
+
+class DataFileReader(object): # pylint: disable=too-many-instance-attributes
+ """Read files written by DataFileWriter."""
+
+ def __init__(self, reader, datum_reader, **kwargs):
+ """Initializes a new data file reader.
+
+ Args:
+ reader: Open file to read from.
+ datum_reader: Avro datum reader.
+ """
+ self._reader = reader
+ self._raw_decoder = avro_io.BinaryDecoder(reader)
+ self._header_reader = kwargs.pop('header_reader', None)
+ self._header_decoder = None if self._header_reader is None else avro_io.BinaryDecoder(self._header_reader)
+ self._datum_decoder = None # Maybe reset at every block.
+ self._datum_reader = datum_reader
+
+ # In case self._reader only has partial content(without header).
+ # seek(0, 0) to make sure read the (partial)content from beginning.
+ self._reader.seek(0, 0)
+
+ # read the header: magic, meta, sync
+ self._read_header()
+
+ # ensure codec is valid
+ avro_codec_raw = self.get_meta('avro.codec')
+ if avro_codec_raw is None:
+ self.codec = "null"
+ else:
+ self.codec = avro_codec_raw.decode('utf-8')
+ if self.codec not in VALID_CODECS:
+ raise DataFileException('Unknown codec: %s.' % self.codec)
+
+ # get ready to read
+ self._block_count = 0
+
+ # object_position is to support reading from current position in the future read,
+ # no need to downloading from the beginning of avro.
+ if hasattr(self._reader, 'object_position'):
+ self.reader.track_object_position()
+
+ self._cur_object_index = 0
+ # header_reader indicates reader only has partial content. The reader doesn't have block header,
+ # so we read use the block count stored last time.
+ # Also ChangeFeed only has codec==null, so use _raw_decoder is good.
+ if self._header_reader is not None:
+ self._datum_decoder = self._raw_decoder
+
+ self.datum_reader.writer_schema = (
+ schema.parse(self.get_meta(SCHEMA_KEY).decode('utf-8')))
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, data_type, value, traceback):
+ # Perform a close if there's no exception
+ if data_type is None:
+ self.close()
+
+ def __iter__(self):
+ return self
+
+ # read-only properties
+ @property
+ def reader(self):
+ return self._reader
+
+ @property
+ def raw_decoder(self):
+ return self._raw_decoder
+
+ @property
+ def datum_decoder(self):
+ return self._datum_decoder
+
+ @property
+ def datum_reader(self):
+ return self._datum_reader
+
+ @property
+ def sync_marker(self):
+ return self._sync_marker
+
+ @property
+ def meta(self):
+ return self._meta
+
+ # read/write properties
+ @property
+ def block_count(self):
+ return self._block_count
+
+ def get_meta(self, key):
+ """Reports the value of a given metadata key.
+
+ Args:
+ key: Metadata key (string) to report the value of.
+ Returns:
+ Value associated to the metadata key, as bytes.
+ """
+ return self._meta.get(key)
+
+ def _read_header(self):
+ header_reader = self._header_reader if self._header_reader else self._reader
+ header_decoder = self._header_decoder if self._header_decoder else self._raw_decoder
+
+ # seek to the beginning of the file to get magic block
+ header_reader.seek(0, 0)
+
+ # read header into a dict
+ header = self.datum_reader.read_data(META_SCHEMA, header_decoder)
+
+ # check magic number
+ if header.get('magic') != MAGIC:
+ fail_msg = "Not an Avro data file: %s doesn't match %s." \
+ % (header.get('magic'), MAGIC)
+ raise schema.AvroException(fail_msg)
+
+ # set metadata
+ self._meta = header['meta']
+
+ # set sync marker
+ self._sync_marker = header['sync']
+
+ def _read_block_header(self):
+ self._block_count = self.raw_decoder.read_long()
+ if self.codec == "null":
+ # Skip a long; we don't need to use the length.
+ self.raw_decoder.skip_long()
+ self._datum_decoder = self._raw_decoder
+ elif self.codec == 'deflate':
+ # Compressed data is stored as (length, data), which
+ # corresponds to how the "bytes" type is encoded.
+ data = self.raw_decoder.read_bytes()
+ # -15 is the log of the window size; negative indicates
+ # "raw" (no zlib headers) decompression. See zlib.h.
+ uncompressed = zlib.decompress(data, -15)
+ self._datum_decoder = avro_io.BinaryDecoder(io.BytesIO(uncompressed))
+ else:
+ raise DataFileException("Unknown codec: %r" % self.codec)
+
+ def _skip_sync(self):
+ """
+ Read the length of the sync marker; if it matches the sync marker,
+ return True. Otherwise, seek back to where we started and return False.
+ """
+ proposed_sync_marker = self.reader.read(SYNC_SIZE)
+ if SYNC_SIZE > 0 and not proposed_sync_marker:
+ raise StopIteration
+ if proposed_sync_marker != self.sync_marker:
+ self.reader.seek(-SYNC_SIZE, 1)
+
+ def __next__(self):
+ """Return the next datum in the file."""
+ if self.block_count == 0:
+ self._skip_sync()
+
+ # object_position is to support reading from current position in the future read,
+ # no need to downloading from the beginning of avro file with this attr.
+ if hasattr(self._reader, 'object_position'):
+ self.reader.track_object_position()
+ self._cur_object_index = 0
+
+ self._read_block_header()
+
+ datum = self.datum_reader.read(self.datum_decoder)
+ self._block_count -= 1
+ self._cur_object_index += 1
+
+ # object_position is to support reading from current position in the future read,
+ # This will track the index of the next item to be read.
+ # This will also track the offset before the next sync marker.
+ if hasattr(self._reader, 'object_position'):
+ if self.block_count == 0:
+ # the next event to be read is at index 0 in the new chunk of blocks,
+ self.reader.track_object_position()
+ self.reader.set_object_index(0)
+ else:
+ self.reader.set_object_index(self._cur_object_index)
+
+ return datum
+
+ # PY2
+ def next(self):
+ return self.__next__()
+
+ def close(self):
+ """Close this reader."""
+ self.reader.close()
+
+
+if __name__ == '__main__':
+ raise Exception('Not a standalone module')
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/datafile_async.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/datafile_async.py
new file mode 100644
index 00000000000..1e9d018228d
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/datafile_async.py
@@ -0,0 +1,215 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+"""Read/Write Avro File Object Containers."""
+
+import logging
+import sys
+
+from ..avro import avro_io_async
+from ..avro import schema
+from .datafile import DataFileException
+from .datafile import MAGIC, SYNC_SIZE, META_SCHEMA, SCHEMA_KEY
+
+
+PY3 = sys.version_info[0] == 3
+
+logger = logging.getLogger(__name__)
+
+# ------------------------------------------------------------------------------
+# Constants
+
+# Codecs supported by container files:
+VALID_CODECS = frozenset(['null'])
+
+
+class AsyncDataFileReader(object): # pylint: disable=too-many-instance-attributes
+ """Read files written by DataFileWriter."""
+
+ def __init__(self, reader, datum_reader, **kwargs):
+ """Initializes a new data file reader.
+
+ Args:
+ reader: Open file to read from.
+ datum_reader: Avro datum reader.
+ """
+ self._reader = reader
+ self._raw_decoder = avro_io_async.AsyncBinaryDecoder(reader)
+ self._header_reader = kwargs.pop('header_reader', None)
+ self._header_decoder = None if self._header_reader is None else \
+ avro_io_async.AsyncBinaryDecoder(self._header_reader)
+ self._datum_decoder = None # Maybe reset at every block.
+ self._datum_reader = datum_reader
+ self.codec = "null"
+ self._block_count = 0
+ self._cur_object_index = 0
+ self._meta = None
+ self._sync_marker = None
+
+ async def init(self):
+ # In case self._reader only has partial content(without header).
+ # seek(0, 0) to make sure read the (partial)content from beginning.
+ await self._reader.seek(0, 0)
+
+ # read the header: magic, meta, sync
+ await self._read_header()
+
+ # ensure codec is valid
+ avro_codec_raw = self.get_meta('avro.codec')
+ if avro_codec_raw is None:
+ self.codec = "null"
+ else:
+ self.codec = avro_codec_raw.decode('utf-8')
+ if self.codec not in VALID_CODECS:
+ raise DataFileException('Unknown codec: %s.' % self.codec)
+
+ # get ready to read
+ self._block_count = 0
+
+ # object_position is to support reading from current position in the future read,
+ # no need to downloading from the beginning of avro.
+ if hasattr(self._reader, 'object_position'):
+ self.reader.track_object_position()
+
+ # header_reader indicates reader only has partial content. The reader doesn't have block header,
+ # so we read use the block count stored last time.
+ # Also ChangeFeed only has codec==null, so use _raw_decoder is good.
+ if self._header_reader is not None:
+ self._datum_decoder = self._raw_decoder
+ self.datum_reader.writer_schema = (
+ schema.parse(self.get_meta(SCHEMA_KEY).decode('utf-8')))
+ return self
+
+ async def __aenter__(self):
+ return self
+
+ async def __aexit__(self, data_type, value, traceback):
+ # Perform a close if there's no exception
+ if data_type is None:
+ self.close()
+
+ def __aiter__(self):
+ return self
+
+ # read-only properties
+ @property
+ def reader(self):
+ return self._reader
+
+ @property
+ def raw_decoder(self):
+ return self._raw_decoder
+
+ @property
+ def datum_decoder(self):
+ return self._datum_decoder
+
+ @property
+ def datum_reader(self):
+ return self._datum_reader
+
+ @property
+ def sync_marker(self):
+ return self._sync_marker
+
+ @property
+ def meta(self):
+ return self._meta
+
+ # read/write properties
+ @property
+ def block_count(self):
+ return self._block_count
+
+ def get_meta(self, key):
+ """Reports the value of a given metadata key.
+
+ Args:
+ key: Metadata key (string) to report the value of.
+ Returns:
+ Value associated to the metadata key, as bytes.
+ """
+ return self._meta.get(key)
+
+ async def _read_header(self):
+ header_reader = self._header_reader if self._header_reader else self._reader
+ header_decoder = self._header_decoder if self._header_decoder else self._raw_decoder
+
+ # seek to the beginning of the file to get magic block
+ await header_reader.seek(0, 0)
+
+ # read header into a dict
+ header = await self.datum_reader.read_data(META_SCHEMA, header_decoder)
+
+ # check magic number
+ if header.get('magic') != MAGIC:
+ fail_msg = "Not an Avro data file: %s doesn't match %s." \
+ % (header.get('magic'), MAGIC)
+ raise schema.AvroException(fail_msg)
+
+ # set metadata
+ self._meta = header['meta']
+
+ # set sync marker
+ self._sync_marker = header['sync']
+
+ async def _read_block_header(self):
+ self._block_count = await self.raw_decoder.read_long()
+ if self.codec == "null":
+ # Skip a long; we don't need to use the length.
+ await self.raw_decoder.skip_long()
+ self._datum_decoder = self._raw_decoder
+ else:
+ raise DataFileException("Unknown codec: %r" % self.codec)
+
+ async def _skip_sync(self):
+ """
+ Read the length of the sync marker; if it matches the sync marker,
+ return True. Otherwise, seek back to where we started and return False.
+ """
+ proposed_sync_marker = await self.reader.read(SYNC_SIZE)
+ if SYNC_SIZE > 0 and not proposed_sync_marker:
+ raise StopAsyncIteration
+ if proposed_sync_marker != self.sync_marker:
+ await self.reader.seek(-SYNC_SIZE, 1)
+
+ async def __anext__(self):
+ """Return the next datum in the file."""
+ if self.block_count == 0:
+ await self._skip_sync()
+
+ # object_position is to support reading from current position in the future read,
+ # no need to downloading from the beginning of avro file with this attr.
+ if hasattr(self._reader, 'object_position'):
+ await self.reader.track_object_position()
+ self._cur_object_index = 0
+
+ await self._read_block_header()
+
+ datum = await self.datum_reader.read(self.datum_decoder)
+ self._block_count -= 1
+ self._cur_object_index += 1
+
+ # object_position is to support reading from current position in the future read,
+ # This will track the index of the next item to be read.
+ # This will also track the offset before the next sync marker.
+ if hasattr(self._reader, 'object_position'):
+ if self.block_count == 0:
+ # the next event to be read is at index 0 in the new chunk of blocks,
+ await self.reader.track_object_position()
+ await self.reader.set_object_index(0)
+ else:
+ await self.reader.set_object_index(self._cur_object_index)
+
+ return datum
+
+ def close(self):
+ """Close this reader."""
+ self.reader.close()
+
+
+if __name__ == '__main__':
+ raise Exception('Not a standalone module')
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/schema.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/schema.py
new file mode 100644
index 00000000000..ffe28530167
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/avro/schema.py
@@ -0,0 +1,1221 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=too-many-lines
+
+"""Representation of Avro schemas.
+
+A schema may be one of:
+ - A record, mapping field names to field value data;
+ - An error, equivalent to a record;
+ - An enum, containing one of a small set of symbols;
+ - An array of values, all of the same schema;
+ - A map containing string/value pairs, each of a declared schema;
+ - A union of other schemas;
+ - A fixed sized binary object;
+ - A unicode string;
+ - A sequence of bytes;
+ - A 32-bit signed int;
+ - A 64-bit signed long;
+ - A 32-bit floating-point float;
+ - A 64-bit floating-point double;
+ - A boolean;
+ - Null.
+"""
+
+import abc
+import json
+import logging
+import re
+import sys
+from six import with_metaclass
+
+PY2 = sys.version_info[0] == 2
+
+if PY2:
+ _str = unicode # pylint: disable=undefined-variable
+else:
+ _str = str
+
+logger = logging.getLogger(__name__)
+
+# ------------------------------------------------------------------------------
+# Constants
+
+# Log level more verbose than DEBUG=10, INFO=20, etc.
+DEBUG_VERBOSE = 5
+
+NULL = 'null'
+BOOLEAN = 'boolean'
+STRING = 'string'
+BYTES = 'bytes'
+INT = 'int'
+LONG = 'long'
+FLOAT = 'float'
+DOUBLE = 'double'
+FIXED = 'fixed'
+ENUM = 'enum'
+RECORD = 'record'
+ERROR = 'error'
+ARRAY = 'array'
+MAP = 'map'
+UNION = 'union'
+
+# Request and error unions are part of Avro protocols:
+REQUEST = 'request'
+ERROR_UNION = 'error_union'
+
+PRIMITIVE_TYPES = frozenset([
+ NULL,
+ BOOLEAN,
+ STRING,
+ BYTES,
+ INT,
+ LONG,
+ FLOAT,
+ DOUBLE,
+])
+
+NAMED_TYPES = frozenset([
+ FIXED,
+ ENUM,
+ RECORD,
+ ERROR,
+])
+
+VALID_TYPES = frozenset.union(
+ PRIMITIVE_TYPES,
+ NAMED_TYPES,
+ [
+ ARRAY,
+ MAP,
+ UNION,
+ REQUEST,
+ ERROR_UNION,
+ ],
+)
+
+SCHEMA_RESERVED_PROPS = frozenset([
+ 'type',
+ 'name',
+ 'namespace',
+ 'fields', # Record
+ 'items', # Array
+ 'size', # Fixed
+ 'symbols', # Enum
+ 'values', # Map
+ 'doc',
+])
+
+FIELD_RESERVED_PROPS = frozenset([
+ 'default',
+ 'name',
+ 'doc',
+ 'order',
+ 'type',
+])
+
+VALID_FIELD_SORT_ORDERS = frozenset([
+ 'ascending',
+ 'descending',
+ 'ignore',
+])
+
+
+# ------------------------------------------------------------------------------
+# Exceptions
+
+
+class Error(Exception):
+ """Base class for errors in this module."""
+
+
+class AvroException(Error):
+ """Generic Avro schema error."""
+
+
+class SchemaParseException(AvroException):
+ """Error while parsing a JSON schema descriptor."""
+
+
+class Schema(with_metaclass(abc.ABCMeta, object)):
+ """Abstract base class for all Schema classes."""
+
+ def __init__(self, data_type, other_props=None):
+ """Initializes a new schema object.
+
+ Args:
+ data_type: Type of the schema to initialize.
+ other_props: Optional dictionary of additional properties.
+ """
+ if data_type not in VALID_TYPES:
+ raise SchemaParseException('%r is not a valid Avro type.' % data_type)
+
+ # All properties of this schema, as a map: property name -> property value
+ self._props = {}
+
+ self._props['type'] = data_type
+ self._type = data_type
+
+ if other_props:
+ self._props.update(other_props)
+
+ @property
+ def namespace(self):
+ """Returns: the namespace this schema belongs to, if any, or None."""
+ return self._props.get('namespace', None)
+
+ @property
+ def type(self):
+ """Returns: the type of this schema."""
+ return self._type
+
+ @property
+ def doc(self):
+ """Returns: the documentation associated to this schema, if any, or None."""
+ return self._props.get('doc', None)
+
+ @property
+ def props(self):
+ """Reports all the properties of this schema.
+
+ Includes all properties, reserved and non reserved.
+ JSON properties of this schema are directly generated from this dict.
+
+ Returns:
+ A dictionary of properties associated to this schema.
+ """
+ return self._props
+
+ @property
+ def other_props(self):
+ """Returns: the dictionary of non-reserved properties."""
+ return dict(filter_keys_out(items=self._props, keys=SCHEMA_RESERVED_PROPS))
+
+ def __str__(self):
+ """Returns: the JSON representation of this schema."""
+ return json.dumps(self.to_json(names=None))
+
+ @abc.abstractmethod
+ def to_json(self, names):
+ """Converts the schema object into its AVRO specification representation.
+
+ Schema types that have names (records, enums, and fixed) must
+ be aware of not re-defining schemas that are already listed
+ in the parameter names.
+ """
+ raise Exception('Cannot run abstract method.')
+
+
+# ------------------------------------------------------------------------------
+
+
+_RE_NAME = re.compile(r'[A-Za-z_][A-Za-z0-9_]*')
+
+_RE_FULL_NAME = re.compile(
+ r'^'
+ r'[.]?(?:[A-Za-z_][A-Za-z0-9_]*[.])*' # optional namespace
+ r'([A-Za-z_][A-Za-z0-9_]*)' # name
+ r'$'
+)
+
+
+class Name(object):
+ """Representation of an Avro name."""
+
+ def __init__(self, name, namespace=None):
+ """Parses an Avro name.
+
+ Args:
+ name: Avro name to parse (relative or absolute).
+ namespace: Optional explicit namespace if the name is relative.
+ """
+ # Normalize: namespace is always defined as a string, possibly empty.
+ if namespace is None:
+ namespace = ''
+
+ if '.' in name:
+ # name is absolute, namespace is ignored:
+ self._fullname = name
+
+ match = _RE_FULL_NAME.match(self._fullname)
+ if match is None:
+ raise SchemaParseException(
+ 'Invalid absolute schema name: %r.' % self._fullname)
+
+ self._name = match.group(1)
+ self._namespace = self._fullname[:-(len(self._name) + 1)]
+
+ else:
+ # name is relative, combine with explicit namespace:
+ self._name = name
+ self._namespace = namespace
+ self._fullname = (self._name
+ if (not self._namespace) else
+ '%s.%s' % (self._namespace, self._name))
+
+ # Validate the fullname:
+ if _RE_FULL_NAME.match(self._fullname) is None:
+ raise SchemaParseException(
+ 'Invalid schema name %r infered from name %r and namespace %r.'
+ % (self._fullname, self._name, self._namespace))
+
+ def __eq__(self, other):
+ if not isinstance(other, Name):
+ return NotImplemented
+ return self.fullname == other.fullname
+
+ @property
+ def simple_name(self):
+ """Returns: the simple name part of this name."""
+ return self._name
+
+ @property
+ def namespace(self):
+ """Returns: this name's namespace, possible the empty string."""
+ return self._namespace
+
+ @property
+ def fullname(self):
+ """Returns: the full name."""
+ return self._fullname
+
+
+# ------------------------------------------------------------------------------
+
+
+class Names(object):
+ """Tracks Avro named schemas and default namespace during parsing."""
+
+ def __init__(self, default_namespace=None, names=None):
+ """Initializes a new name tracker.
+
+ Args:
+ default_namespace: Optional default namespace.
+ names: Optional initial mapping of known named schemas.
+ """
+ if names is None:
+ names = {}
+ self._names = names
+ self._default_namespace = default_namespace
+
+ @property
+ def names(self):
+ """Returns: the mapping of known named schemas."""
+ return self._names
+
+ @property
+ def default_namespace(self):
+ """Returns: the default namespace, if any, or None."""
+ return self._default_namespace
+
+ def new_with_default_namespace(self, namespace):
+ """Creates a new name tracker from this tracker, but with a new default ns.
+
+ Args:
+ namespace: New default namespace to use.
+ Returns:
+ New name tracker with the specified default namespace.
+ """
+ return Names(names=self._names, default_namespace=namespace)
+
+ def get_name(self, name, namespace=None):
+ """Resolves the Avro name according to this name tracker's state.
+
+ Args:
+ name: Name to resolve (absolute or relative).
+ namespace: Optional explicit namespace.
+ Returns:
+ The specified name, resolved according to this tracker.
+ """
+ if namespace is None:
+ namespace = self._default_namespace
+ return Name(name=name, namespace=namespace)
+
+ def get_schema(self, name, namespace=None):
+ """Resolves an Avro schema by name.
+
+ Args:
+ name: Name (relative or absolute) of the Avro schema to look up.
+ namespace: Optional explicit namespace.
+ Returns:
+ The schema with the specified name, if any, or None.
+ """
+ avro_name = self.get_name(name=name, namespace=namespace)
+ return self._names.get(avro_name.fullname, None)
+
+ def prune_namespace(self, properties):
+ """given a properties, return properties with namespace removed if
+ it matches the own default namespace
+ """
+ if self.default_namespace is None:
+ # I have no default -- no change
+ return properties
+ if 'namespace' not in properties:
+ # he has no namespace - no change
+ return properties
+ if properties['namespace'] != self.default_namespace:
+ # we're different - leave his stuff alone
+ return properties
+ # we each have a namespace and it's redundant. delete his.
+ prunable = properties.copy()
+ del prunable['namespace']
+ return prunable
+
+ def register(self, schema):
+ """Registers a new named schema in this tracker.
+
+ Args:
+ schema: Named Avro schema to register in this tracker.
+ """
+ if schema.fullname in VALID_TYPES:
+ raise SchemaParseException(
+ '%s is a reserved type name.' % schema.fullname)
+ if schema.fullname in self.names:
+ raise SchemaParseException(
+ 'Avro name %r already exists.' % schema.fullname)
+
+ logger.log(DEBUG_VERBOSE, 'Register new name for %r', schema.fullname)
+ self._names[schema.fullname] = schema
+
+
+# ------------------------------------------------------------------------------
+
+
+class NamedSchema(Schema):
+ """Abstract base class for named schemas.
+
+ Named schemas are enumerated in NAMED_TYPES.
+ """
+
+ def __init__(
+ self,
+ data_type,
+ name=None,
+ namespace=None,
+ names=None,
+ other_props=None,
+ ):
+ """Initializes a new named schema object.
+
+ Args:
+ data_type: Type of the named schema.
+ name: Name (absolute or relative) of the schema.
+ namespace: Optional explicit namespace if name is relative.
+ names: Tracker to resolve and register Avro names.
+ other_props: Optional map of additional properties of the schema.
+ """
+ assert (data_type in NAMED_TYPES), ('Invalid named type: %r' % data_type)
+ self._avro_name = names.get_name(name=name, namespace=namespace)
+
+ super(NamedSchema, self).__init__(data_type, other_props)
+
+ names.register(self)
+
+ self._props['name'] = self.name
+ if self.namespace:
+ self._props['namespace'] = self.namespace
+
+ @property
+ def avro_name(self):
+ """Returns: the Name object describing this schema's name."""
+ return self._avro_name
+
+ @property
+ def name(self):
+ return self._avro_name.simple_name
+
+ @property
+ def namespace(self):
+ return self._avro_name.namespace
+
+ @property
+ def fullname(self):
+ return self._avro_name.fullname
+
+ def name_ref(self, names):
+ """Reports this schema name relative to the specified name tracker.
+
+ Args:
+ names: Avro name tracker to relativise this schema name against.
+ Returns:
+ This schema name, relativised against the specified name tracker.
+ """
+ if self.namespace == names.default_namespace:
+ return self.name
+ return self.fullname
+
+ @abc.abstractmethod
+ def to_json(self, names):
+ """Converts the schema object into its AVRO specification representation.
+
+ Schema types that have names (records, enums, and fixed) must
+ be aware of not re-defining schemas that are already listed
+ in the parameter names.
+ """
+ raise Exception('Cannot run abstract method.')
+
+# ------------------------------------------------------------------------------
+
+
+_NO_DEFAULT = object()
+
+
+class Field(object):
+ """Representation of the schema of a field in a record."""
+
+ def __init__(
+ self,
+ data_type,
+ name,
+ index,
+ has_default,
+ default=_NO_DEFAULT,
+ order=None,
+ doc=None,
+ other_props=None
+ ):
+ """Initializes a new Field object.
+
+ Args:
+ data_type: Avro schema of the field.
+ name: Name of the field.
+ index: 0-based position of the field.
+ has_default:
+ default:
+ order:
+ doc:
+ other_props:
+ """
+ if (not isinstance(name, _str)) or (not name):
+ raise SchemaParseException('Invalid record field name: %r.' % name)
+ if (order is not None) and (order not in VALID_FIELD_SORT_ORDERS):
+ raise SchemaParseException('Invalid record field order: %r.' % order)
+
+ # All properties of this record field:
+ self._props = {}
+
+ self._has_default = has_default
+ if other_props:
+ self._props.update(other_props)
+
+ self._index = index
+ self._type = self._props['type'] = data_type
+ self._name = self._props['name'] = name
+
+ if has_default:
+ self._props['default'] = default
+
+ if order is not None:
+ self._props['order'] = order
+
+ if doc is not None:
+ self._props['doc'] = doc
+
+ @property
+ def type(self):
+ """Returns: the schema of this field."""
+ return self._type
+
+ @property
+ def name(self):
+ """Returns: this field name."""
+ return self._name
+
+ @property
+ def index(self):
+ """Returns: the 0-based index of this field in the record."""
+ return self._index
+
+ @property
+ def default(self):
+ return self._props['default']
+
+ @property
+ def has_default(self):
+ return self._has_default
+
+ @property
+ def order(self):
+ return self._props.get('order', None)
+
+ @property
+ def doc(self):
+ return self._props.get('doc', None)
+
+ @property
+ def props(self):
+ return self._props
+
+ @property
+ def other_props(self):
+ return filter_keys_out(items=self._props, keys=FIELD_RESERVED_PROPS)
+
+ def __str__(self):
+ return json.dumps(self.to_json())
+
+ def to_json(self, names=None):
+ if names is None:
+ names = Names()
+ to_dump = self.props.copy()
+ to_dump['type'] = self.type.to_json(names)
+ return to_dump
+
+ def __eq__(self, that):
+ to_cmp = json.loads(_str(self))
+ return to_cmp == json.loads(_str(that))
+
+
+# ------------------------------------------------------------------------------
+# Primitive Types
+
+
+class PrimitiveSchema(Schema):
+ """Schema of a primitive Avro type.
+
+ Valid primitive types are defined in PRIMITIVE_TYPES.
+ """
+
+ def __init__(self, data_type, other_props=None):
+ """Initializes a new schema object for the specified primitive type.
+
+ Args:
+ data_type: Type of the schema to construct. Must be primitive.
+ """
+ if data_type not in PRIMITIVE_TYPES:
+ raise AvroException('%r is not a valid primitive type.' % data_type)
+ super(PrimitiveSchema, self).__init__(data_type, other_props=other_props)
+
+ @property
+ def name(self):
+ """Returns: the simple name of this schema."""
+ # The name of a primitive type is the type itself.
+ return self.type
+
+ @property
+ def fullname(self):
+ """Returns: the fully qualified name of this schema."""
+ # The full name is the simple name for primitive schema.
+ return self.name
+
+ def to_json(self, names=None):
+ if len(self.props) == 1:
+ return self.fullname
+ return self.props
+
+ def __eq__(self, that):
+ return self.props == that.props
+
+
+# ------------------------------------------------------------------------------
+# Complex Types (non-recursive)
+
+
+class FixedSchema(NamedSchema):
+ def __init__(
+ self,
+ name,
+ namespace,
+ size,
+ names=None,
+ other_props=None,
+ ):
+ # Ensure valid ctor args
+ if not isinstance(size, int):
+ fail_msg = 'Fixed Schema requires a valid integer for size property.'
+ raise AvroException(fail_msg)
+
+ super(FixedSchema, self).__init__(
+ data_type=FIXED,
+ name=name,
+ namespace=namespace,
+ names=names,
+ other_props=other_props,
+ )
+ self._props['size'] = size
+
+ @property
+ def size(self):
+ """Returns: the size of this fixed schema, in bytes."""
+ return self._props['size']
+
+ def to_json(self, names=None):
+ if names is None:
+ names = Names()
+ if self.fullname in names.names:
+ return self.name_ref(names)
+ names.names[self.fullname] = self
+ return names.prune_namespace(self.props)
+
+ def __eq__(self, that):
+ return self.props == that.props
+
+
+# ------------------------------------------------------------------------------
+
+
+class EnumSchema(NamedSchema):
+ def __init__(
+ self,
+ name,
+ namespace,
+ symbols,
+ names=None,
+ doc=None,
+ other_props=None,
+ ):
+ """Initializes a new enumeration schema object.
+
+ Args:
+ name: Simple name of this enumeration.
+ namespace: Optional namespace.
+ symbols: Ordered list of symbols defined in this enumeration.
+ names:
+ doc:
+ other_props:
+ """
+ symbols = tuple(symbols)
+ symbol_set = frozenset(symbols)
+ if (len(symbol_set) != len(symbols)
+ or not all(map(lambda symbol: isinstance(symbol, _str), symbols))):
+ raise AvroException(
+ 'Invalid symbols for enum schema: %r.' % (symbols,))
+
+ super(EnumSchema, self).__init__(
+ data_type=ENUM,
+ name=name,
+ namespace=namespace,
+ names=names,
+ other_props=other_props,
+ )
+
+ self._props['symbols'] = symbols
+ if doc is not None:
+ self._props['doc'] = doc
+
+ @property
+ def symbols(self):
+ """Returns: the symbols defined in this enum."""
+ return self._props['symbols']
+
+ def to_json(self, names=None):
+ if names is None:
+ names = Names()
+ if self.fullname in names.names:
+ return self.name_ref(names)
+ names.names[self.fullname] = self
+ return names.prune_namespace(self.props)
+
+ def __eq__(self, that):
+ return self.props == that.props
+
+
+# ------------------------------------------------------------------------------
+# Complex Types (recursive)
+
+
+class ArraySchema(Schema):
+ """Schema of an array."""
+
+ def __init__(self, items, other_props=None):
+ """Initializes a new array schema object.
+
+ Args:
+ items: Avro schema of the array items.
+ other_props:
+ """
+ super(ArraySchema, self).__init__(
+ data_type=ARRAY,
+ other_props=other_props,
+ )
+ self._items_schema = items
+ self._props['items'] = items
+
+ @property
+ def items(self):
+ """Returns: the schema of the items in this array."""
+ return self._items_schema
+
+ def to_json(self, names=None):
+ if names is None:
+ names = Names()
+ to_dump = self.props.copy()
+ item_schema = self.items
+ to_dump['items'] = item_schema.to_json(names)
+ return to_dump
+
+ def __eq__(self, that):
+ to_cmp = json.loads(_str(self))
+ return to_cmp == json.loads(_str(that))
+
+
+# ------------------------------------------------------------------------------
+
+
+class MapSchema(Schema):
+ """Schema of a map."""
+
+ def __init__(self, values, other_props=None):
+ """Initializes a new map schema object.
+
+ Args:
+ values: Avro schema of the map values.
+ other_props:
+ """
+ super(MapSchema, self).__init__(
+ data_type=MAP,
+ other_props=other_props,
+ )
+ self._values_schema = values
+ self._props['values'] = values
+
+ @property
+ def values(self):
+ """Returns: the schema of the values in this map."""
+ return self._values_schema
+
+ def to_json(self, names=None):
+ if names is None:
+ names = Names()
+ to_dump = self.props.copy()
+ to_dump['values'] = self.values.to_json(names)
+ return to_dump
+
+ def __eq__(self, that):
+ to_cmp = json.loads(_str(self))
+ return to_cmp == json.loads(_str(that))
+
+
+# ------------------------------------------------------------------------------
+
+
+class UnionSchema(Schema):
+ """Schema of a union."""
+
+ def __init__(self, schemas):
+ """Initializes a new union schema object.
+
+ Args:
+ schemas: Ordered collection of schema branches in the union.
+ """
+ super(UnionSchema, self).__init__(data_type=UNION)
+ self._schemas = tuple(schemas)
+
+ # Validate the schema branches:
+
+ # All named schema names are unique:
+ named_branches = tuple(
+ filter(lambda schema: schema.type in NAMED_TYPES, self._schemas))
+ unique_names = frozenset(map(lambda schema: schema.fullname, named_branches))
+ if len(unique_names) != len(named_branches):
+ raise AvroException(
+ 'Invalid union branches with duplicate schema name:%s'
+ % ''.join(map(lambda schema: ('\n\t - %s' % schema), self._schemas)))
+
+ # Types are unique within unnamed schemas, and union is not allowed:
+ unnamed_branches = tuple(
+ filter(lambda schema: schema.type not in NAMED_TYPES, self._schemas))
+ unique_types = frozenset(map(lambda schema: schema.type, unnamed_branches))
+ if UNION in unique_types:
+ raise AvroException(
+ 'Invalid union branches contain other unions:%s'
+ % ''.join(map(lambda schema: ('\n\t - %s' % schema), self._schemas)))
+ if len(unique_types) != len(unnamed_branches):
+ raise AvroException(
+ 'Invalid union branches with duplicate type:%s'
+ % ''.join(map(lambda schema: ('\n\t - %s' % schema), self._schemas)))
+
+ @property
+ def schemas(self):
+ """Returns: the ordered list of schema branches in the union."""
+ return self._schemas
+
+ def to_json(self, names=None):
+ if names is None:
+ names = Names()
+ to_dump = []
+ for schema in self.schemas:
+ to_dump.append(schema.to_json(names))
+ return to_dump
+
+ def __eq__(self, that):
+ to_cmp = json.loads(_str(self))
+ return to_cmp == json.loads(_str(that))
+
+
+# ------------------------------------------------------------------------------
+
+
+class ErrorUnionSchema(UnionSchema):
+ """Schema representing the declared errors of a protocol message."""
+
+ def __init__(self, schemas):
+ """Initializes an error-union schema.
+
+ Args:
+ schema: collection of error schema.
+ """
+ # Prepend "string" to handle system errors
+ schemas = [PrimitiveSchema(data_type=STRING)] + list(schemas)
+ super(ErrorUnionSchema, self).__init__(schemas=schemas)
+
+ def to_json(self, names=None):
+ if names is None:
+ names = Names()
+ to_dump = []
+ for schema in self.schemas:
+ # Don't print the system error schema
+ if schema.type == STRING:
+ continue
+ to_dump.append(schema.to_json(names))
+ return to_dump
+
+
+# ------------------------------------------------------------------------------
+
+
+class RecordSchema(NamedSchema):
+ """Schema of a record."""
+
+ @staticmethod
+ def _make_field(index, field_desc, names):
+ """Builds field schemas from a list of field JSON descriptors.
+
+ Args:
+ index: 0-based index of the field in the record.
+ field_desc: JSON descriptors of a record field.
+ Return:
+ The field schema.
+ """
+ field_schema = schema_from_json_data(
+ json_data=field_desc['type'],
+ names=names,
+ )
+ other_props = (
+ dict(filter_keys_out(items=field_desc, keys=FIELD_RESERVED_PROPS)))
+ return Field(
+ data_type=field_schema,
+ name=field_desc['name'],
+ index=index,
+ has_default=('default' in field_desc),
+ default=field_desc.get('default', _NO_DEFAULT),
+ order=field_desc.get('order', None),
+ doc=field_desc.get('doc', None),
+ other_props=other_props,
+ )
+
+ @staticmethod
+ def make_field_list(field_desc_list, names):
+ """Builds field schemas from a list of field JSON descriptors.
+
+ Guarantees field name unicity.
+
+ Args:
+ field_desc_list: collection of field JSON descriptors.
+ names: Avro schema tracker.
+ Yields
+ Field schemas.
+ """
+ for index, field_desc in enumerate(field_desc_list):
+ yield RecordSchema._make_field(index, field_desc, names)
+
+ @staticmethod
+ def _make_field_map(fields):
+ """Builds the field map.
+
+ Guarantees field name unicity.
+
+ Args:
+ fields: iterable of field schema.
+ Returns:
+ A map of field schemas, indexed by name.
+ """
+ field_map = {}
+ for field in fields:
+ if field.name in field_map:
+ raise SchemaParseException(
+ 'Duplicate record field name %r.' % field.name)
+ field_map[field.name] = field
+ return field_map
+
+ def __init__(
+ self,
+ name,
+ namespace,
+ fields=None,
+ make_fields=None,
+ names=None,
+ record_type=RECORD,
+ doc=None,
+ other_props=None
+ ):
+ """Initializes a new record schema object.
+
+ Args:
+ name: Name of the record (absolute or relative).
+ namespace: Optional namespace the record belongs to, if name is relative.
+ fields: collection of fields to add to this record.
+ Exactly one of fields or make_fields must be specified.
+ make_fields: function creating the fields that belong to the record.
+ The function signature is: make_fields(names) -> ordered field list.
+ Exactly one of fields or make_fields must be specified.
+ names:
+ record_type: Type of the record: one of RECORD, ERROR or REQUEST.
+ Protocol requests are not named.
+ doc:
+ other_props:
+ """
+ if record_type == REQUEST:
+ # Protocol requests are not named:
+ super(RecordSchema, self).__init__(
+ data_type=REQUEST,
+ other_props=other_props,
+ )
+ elif record_type in [RECORD, ERROR]:
+ # Register this record name in the tracker:
+ super(RecordSchema, self).__init__(
+ data_type=record_type,
+ name=name,
+ namespace=namespace,
+ names=names,
+ other_props=other_props,
+ )
+ else:
+ raise SchemaParseException(
+ 'Invalid record type: %r.' % record_type)
+
+ if record_type in [RECORD, ERROR]:
+ avro_name = names.get_name(name=name, namespace=namespace)
+ nested_names = names.new_with_default_namespace(namespace=avro_name.namespace)
+ elif record_type == REQUEST:
+ # Protocol request has no name: no need to change default namespace:
+ nested_names = names
+
+ if fields is None:
+ fields = make_fields(names=nested_names)
+ else:
+ assert make_fields is None
+ self._fields = tuple(fields)
+
+ self._field_map = RecordSchema._make_field_map(self._fields)
+
+ self._props['fields'] = fields
+ if doc is not None:
+ self._props['doc'] = doc
+
+ @property
+ def fields(self):
+ """Returns: the field schemas, as an ordered tuple."""
+ return self._fields
+
+ @property
+ def field_map(self):
+ """Returns: a read-only map of the field schemas index by field names."""
+ return self._field_map
+
+ def to_json(self, names=None):
+ if names is None:
+ names = Names()
+ # Request records don't have names
+ if self.type == REQUEST:
+ return [f.to_json(names) for f in self.fields]
+
+ if self.fullname in names.names:
+ return self.name_ref(names)
+ names.names[self.fullname] = self
+
+ to_dump = names.prune_namespace(self.props.copy())
+ to_dump['fields'] = [f.to_json(names) for f in self.fields]
+ return to_dump
+
+ def __eq__(self, that):
+ to_cmp = json.loads(_str(self))
+ return to_cmp == json.loads(_str(that))
+
+
+# ------------------------------------------------------------------------------
+# Module functions
+
+
+def filter_keys_out(items, keys):
+ """Filters a collection of (key, value) items.
+
+ Exclude any item whose key belongs to keys.
+
+ Args:
+ items: Dictionary of items to filter the keys out of.
+ keys: Keys to filter out.
+ Yields:
+ Filtered items.
+ """
+ for key, value in items.items():
+ if key in keys:
+ continue
+ yield key, value
+
+
+# ------------------------------------------------------------------------------
+
+
+def _schema_from_json_string(json_string, names):
+ if json_string in PRIMITIVE_TYPES:
+ return PrimitiveSchema(data_type=json_string)
+
+ # Look for a known named schema:
+ schema = names.get_schema(name=json_string)
+ if schema is None:
+ raise SchemaParseException(
+ 'Unknown named schema %r, known names: %r.'
+ % (json_string, sorted(names.names)))
+ return schema
+
+
+def _schema_from_json_array(json_array, names):
+ def MakeSchema(desc):
+ return schema_from_json_data(json_data=desc, names=names)
+
+ return UnionSchema(map(MakeSchema, json_array))
+
+
+def _schema_from_json_object(json_object, names):
+ data_type = json_object.get('type')
+ if data_type is None:
+ raise SchemaParseException(
+ 'Avro schema JSON descriptor has no "type" property: %r' % json_object)
+
+ other_props = dict(
+ filter_keys_out(items=json_object, keys=SCHEMA_RESERVED_PROPS))
+
+ if data_type in PRIMITIVE_TYPES:
+ # FIXME should not ignore other properties
+ result = PrimitiveSchema(data_type, other_props=other_props)
+
+ elif data_type in NAMED_TYPES:
+ name = json_object.get('name')
+ namespace = json_object.get('namespace', names.default_namespace)
+ if data_type == FIXED:
+ size = json_object.get('size')
+ result = FixedSchema(name, namespace, size, names, other_props)
+ elif data_type == ENUM:
+ symbols = json_object.get('symbols')
+ doc = json_object.get('doc')
+ result = EnumSchema(name, namespace, symbols, names, doc, other_props)
+
+ elif data_type in [RECORD, ERROR]:
+ field_desc_list = json_object.get('fields', ())
+
+ def MakeFields(names):
+ return tuple(RecordSchema.make_field_list(field_desc_list, names))
+
+ result = RecordSchema(
+ name=name,
+ namespace=namespace,
+ make_fields=MakeFields,
+ names=names,
+ record_type=data_type,
+ doc=json_object.get('doc'),
+ other_props=other_props,
+ )
+ else:
+ raise Exception('Internal error: unknown type %r.' % data_type)
+
+ elif data_type in VALID_TYPES:
+ # Unnamed, non-primitive Avro type:
+
+ if data_type == ARRAY:
+ items_desc = json_object.get('items')
+ if items_desc is None:
+ raise SchemaParseException(
+ 'Invalid array schema descriptor with no "items" : %r.'
+ % json_object)
+ result = ArraySchema(
+ items=schema_from_json_data(items_desc, names),
+ other_props=other_props,
+ )
+
+ elif data_type == MAP:
+ values_desc = json_object.get('values')
+ if values_desc is None:
+ raise SchemaParseException(
+ 'Invalid map schema descriptor with no "values" : %r.'
+ % json_object)
+ result = MapSchema(
+ values=schema_from_json_data(values_desc, names=names),
+ other_props=other_props,
+ )
+
+ elif data_type == ERROR_UNION:
+ error_desc_list = json_object.get('declared_errors')
+ assert error_desc_list is not None
+ error_schemas = map(
+ lambda desc: schema_from_json_data(desc, names=names),
+ error_desc_list)
+ result = ErrorUnionSchema(schemas=error_schemas)
+
+ else:
+ raise Exception('Internal error: unknown type %r.' % data_type)
+ else:
+ raise SchemaParseException(
+ 'Invalid JSON descriptor for an Avro schema: %r' % json_object)
+ return result
+
+
+# Parsers for the JSON data types:
+_JSONDataParserTypeMap = {
+ _str: _schema_from_json_string,
+ list: _schema_from_json_array,
+ dict: _schema_from_json_object,
+}
+
+
+def schema_from_json_data(json_data, names=None):
+ """Builds an Avro Schema from its JSON descriptor.
+
+ Args:
+ json_data: JSON data representing the descriptor of the Avro schema.
+ names: Optional tracker for Avro named schemas.
+ Returns:
+ The Avro schema parsed from the JSON descriptor.
+ Raises:
+ SchemaParseException: if the descriptor is invalid.
+ """
+ if names is None:
+ names = Names()
+
+ # Select the appropriate parser based on the JSON data type:
+ parser = _JSONDataParserTypeMap.get(type(json_data))
+ if parser is None:
+ raise SchemaParseException(
+ 'Invalid JSON descriptor for an Avro schema: %r.' % json_data)
+ return parser(json_data, names=names)
+
+
+# ------------------------------------------------------------------------------
+
+
+def parse(json_string):
+ """Constructs a Schema from its JSON descriptor in text form.
+
+ Args:
+ json_string: String representation of the JSON descriptor of the schema.
+ Returns:
+ The parsed schema.
+ Raises:
+ SchemaParseException: on JSON parsing error,
+ or if the JSON descriptor is invalid.
+ """
+ try:
+ json_data = json.loads(json_string)
+ except Exception as exn:
+ raise SchemaParseException(
+ 'Error parsing schema from JSON: %r. '
+ 'Error message: %r.'
+ % (json_string, exn))
+
+ # Initialize the names object
+ names = Names()
+
+ # construct the Avro Schema object
+ return schema_from_json_data(json_data, names)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/base_client.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/base_client.py
new file mode 100644
index 00000000000..9784a278ab7
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/base_client.py
@@ -0,0 +1,463 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+import logging
+import uuid
+from typing import ( # pylint: disable=unused-import
+ Optional,
+ Any,
+ Tuple,
+)
+
+try:
+ from urllib.parse import parse_qs, quote
+except ImportError:
+ from urlparse import parse_qs # type: ignore
+ from urllib2 import quote # type: ignore
+
+import six
+
+from azure.core.configuration import Configuration
+from azure.core.credentials import AzureSasCredential
+from azure.core.exceptions import HttpResponseError
+from azure.core.pipeline import Pipeline
+from azure.core.pipeline.transport import RequestsTransport, HttpTransport
+from azure.core.pipeline.policies import (
+ AzureSasCredentialPolicy,
+ ContentDecodePolicy,
+ DistributedTracingPolicy,
+ HttpLoggingPolicy,
+ RedirectPolicy,
+ ProxyPolicy,
+ UserAgentPolicy,
+)
+
+from .constants import CONNECTION_TIMEOUT, READ_TIMEOUT, SERVICE_HOST_BASE
+from .models import LocationMode
+from .authentication import SharedKeyCredentialPolicy
+from .shared_access_signature import QueryStringConstants
+from .request_handlers import serialize_batch_body, _get_batch_request_delimiter
+from .policies import (
+ ExponentialRetry,
+ StorageBearerTokenCredentialPolicy,
+ StorageContentValidation,
+ StorageHeadersPolicy,
+ StorageHosts,
+ StorageLoggingPolicy,
+ StorageRequestHook,
+ StorageResponseHook,
+ QueueMessagePolicy,
+)
+from .._version import VERSION
+from .response_handlers import process_storage_error, PartialBatchErrorException
+
+
+_LOGGER = logging.getLogger(__name__)
+_SERVICE_PARAMS = {
+ "blob": {"primary": "BLOBENDPOINT", "secondary": "BLOBSECONDARYENDPOINT"},
+ "queue": {"primary": "QUEUEENDPOINT", "secondary": "QUEUESECONDARYENDPOINT"},
+ "file": {"primary": "FILEENDPOINT", "secondary": "FILESECONDARYENDPOINT"},
+ "dfs": {"primary": "BLOBENDPOINT", "secondary": "BLOBENDPOINT"},
+}
+
+
+class StorageAccountHostsMixin(object): # pylint: disable=too-many-instance-attributes
+ def __init__(
+ self,
+ parsed_url, # type: Any
+ service, # type: str
+ credential=None, # type: Optional[Any]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> None
+ self._location_mode = kwargs.get("_location_mode", LocationMode.PRIMARY)
+ self._hosts = kwargs.get("_hosts")
+ self.scheme = parsed_url.scheme
+
+ if service not in ["blob", "queue", "file-share", "dfs"]:
+ raise ValueError("Invalid service: {}".format(service))
+ service_name = service.split('-')[0]
+ account = parsed_url.netloc.split(".{}.core.".format(service_name))
+
+ self.account_name = account[0] if len(account) > 1 else None
+ if not self.account_name and parsed_url.netloc.startswith("localhost") \
+ or parsed_url.netloc.startswith("127.0.0.1"):
+ self.account_name = parsed_url.path.strip("/")
+
+ self.credential = _format_shared_key_credential(self.account_name, credential)
+ if self.scheme.lower() != "https" and hasattr(self.credential, "get_token"):
+ raise ValueError("Token credential is only supported with HTTPS.")
+
+ secondary_hostname = None
+ if hasattr(self.credential, "account_name"):
+ self.account_name = self.credential.account_name
+ secondary_hostname = "{}-secondary.{}.{}".format(
+ self.credential.account_name, service_name, SERVICE_HOST_BASE)
+
+ if not self._hosts:
+ if len(account) > 1:
+ secondary_hostname = parsed_url.netloc.replace(account[0], account[0] + "-secondary")
+ if kwargs.get("secondary_hostname"):
+ secondary_hostname = kwargs["secondary_hostname"]
+ primary_hostname = (parsed_url.netloc + parsed_url.path).rstrip('/')
+ self._hosts = {LocationMode.PRIMARY: primary_hostname, LocationMode.SECONDARY: secondary_hostname}
+
+ self.require_encryption = kwargs.get("require_encryption", False)
+ self.key_encryption_key = kwargs.get("key_encryption_key")
+ self.key_resolver_function = kwargs.get("key_resolver_function")
+ self._config, self._pipeline = self._create_pipeline(self.credential, storage_sdk=service, **kwargs)
+
+ def __enter__(self):
+ self._client.__enter__()
+ return self
+
+ def __exit__(self, *args):
+ self._client.__exit__(*args)
+
+ def close(self):
+ """ This method is to close the sockets opened by the client.
+ It need not be used when using with a context manager.
+ """
+ self._client.close()
+
+ @property
+ def url(self):
+ """The full endpoint URL to this entity, including SAS token if used.
+
+ This could be either the primary endpoint,
+ or the secondary endpoint depending on the current :func:`location_mode`.
+ """
+ return self._format_url(self._hosts[self._location_mode])
+
+ @property
+ def primary_endpoint(self):
+ """The full primary endpoint URL.
+
+ :type: str
+ """
+ return self._format_url(self._hosts[LocationMode.PRIMARY])
+
+ @property
+ def primary_hostname(self):
+ """The hostname of the primary endpoint.
+
+ :type: str
+ """
+ return self._hosts[LocationMode.PRIMARY]
+
+ @property
+ def secondary_endpoint(self):
+ """The full secondary endpoint URL if configured.
+
+ If not available a ValueError will be raised. To explicitly specify a secondary hostname, use the optional
+ `secondary_hostname` keyword argument on instantiation.
+
+ :type: str
+ :raise ValueError:
+ """
+ if not self._hosts[LocationMode.SECONDARY]:
+ raise ValueError("No secondary host configured.")
+ return self._format_url(self._hosts[LocationMode.SECONDARY])
+
+ @property
+ def secondary_hostname(self):
+ """The hostname of the secondary endpoint.
+
+ If not available this will be None. To explicitly specify a secondary hostname, use the optional
+ `secondary_hostname` keyword argument on instantiation.
+
+ :type: str or None
+ """
+ return self._hosts[LocationMode.SECONDARY]
+
+ @property
+ def location_mode(self):
+ """The location mode that the client is currently using.
+
+ By default this will be "primary". Options include "primary" and "secondary".
+
+ :type: str
+ """
+
+ return self._location_mode
+
+ @location_mode.setter
+ def location_mode(self, value):
+ if self._hosts.get(value):
+ self._location_mode = value
+ self._client._config.url = self.url # pylint: disable=protected-access
+ else:
+ raise ValueError("No host URL for location mode: {}".format(value))
+
+ @property
+ def api_version(self):
+ """The version of the Storage API used for requests.
+
+ :type: str
+ """
+ return self._client._config.version # pylint: disable=protected-access
+
+ def _format_query_string(self, sas_token, credential, snapshot=None, share_snapshot=None):
+ query_str = "?"
+ if snapshot:
+ query_str += "snapshot={}&".format(self.snapshot)
+ if share_snapshot:
+ query_str += "sharesnapshot={}&".format(self.snapshot)
+ if sas_token and isinstance(credential, AzureSasCredential):
+ raise ValueError(
+ "You cannot use AzureSasCredential when the resource URI also contains a Shared Access Signature.")
+ if is_credential_sastoken(credential):
+ query_str += credential.lstrip("?")
+ credential = None
+ elif sas_token:
+ query_str += sas_token
+ return query_str.rstrip("?&"), credential
+
+ def _create_pipeline(self, credential, **kwargs):
+ # type: (Any, **Any) -> Tuple[Configuration, Pipeline]
+ self._credential_policy = None
+ if hasattr(credential, "get_token"):
+ self._credential_policy = StorageBearerTokenCredentialPolicy(credential)
+ elif isinstance(credential, SharedKeyCredentialPolicy):
+ self._credential_policy = credential
+ elif isinstance(credential, AzureSasCredential):
+ self._credential_policy = AzureSasCredentialPolicy(credential)
+ elif credential is not None:
+ raise TypeError("Unsupported credential: {}".format(credential))
+
+ config = kwargs.get("_configuration") or create_configuration(**kwargs)
+ if kwargs.get("_pipeline"):
+ return config, kwargs["_pipeline"]
+ config.transport = kwargs.get("transport") # type: ignore
+ kwargs.setdefault("connection_timeout", CONNECTION_TIMEOUT)
+ kwargs.setdefault("read_timeout", READ_TIMEOUT)
+ if not config.transport:
+ config.transport = RequestsTransport(**kwargs)
+ policies = [
+ QueueMessagePolicy(),
+ config.proxy_policy,
+ config.user_agent_policy,
+ StorageContentValidation(),
+ ContentDecodePolicy(response_encoding="utf-8"),
+ RedirectPolicy(**kwargs),
+ StorageHosts(hosts=self._hosts, **kwargs),
+ config.retry_policy,
+ config.headers_policy,
+ StorageRequestHook(**kwargs),
+ self._credential_policy,
+ config.logging_policy,
+ StorageResponseHook(**kwargs),
+ DistributedTracingPolicy(**kwargs),
+ HttpLoggingPolicy(**kwargs)
+ ]
+ if kwargs.get("_additional_pipeline_policies"):
+ policies = policies + kwargs.get("_additional_pipeline_policies")
+ return config, Pipeline(config.transport, policies=policies)
+
+ def _batch_send(
+ self,
+ *reqs, # type: HttpRequest
+ **kwargs
+ ):
+ """Given a series of request, do a Storage batch call.
+ """
+ # Pop it here, so requests doesn't feel bad about additional kwarg
+ raise_on_any_failure = kwargs.pop("raise_on_any_failure", True)
+ batch_id = str(uuid.uuid1())
+
+ request = self._client._client.post( # pylint: disable=protected-access
+ url='{}://{}/{}?{}comp=batch{}{}'.format(
+ self.scheme,
+ self.primary_hostname,
+ kwargs.pop('path', ""),
+ kwargs.pop('restype', ""),
+ kwargs.pop('sas', ""),
+ kwargs.pop('timeout', "")
+ ),
+ headers={
+ 'x-ms-version': self.api_version,
+ "Content-Type": "multipart/mixed; boundary=" + _get_batch_request_delimiter(batch_id, False, False)
+ }
+ )
+
+ policies = [StorageHeadersPolicy()]
+ if self._credential_policy:
+ policies.append(self._credential_policy)
+
+ request.set_multipart_mixed(
+ *reqs,
+ policies=policies,
+ enforce_https=False
+ )
+
+ Pipeline._prepare_multipart_mixed_request(request) # pylint: disable=protected-access
+ body = serialize_batch_body(request.multipart_mixed_info[0], batch_id)
+ request.set_bytes_body(body)
+
+ temp = request.multipart_mixed_info
+ request.multipart_mixed_info = None
+ pipeline_response = self._pipeline.run(
+ request, **kwargs
+ )
+ response = pipeline_response.http_response
+ request.multipart_mixed_info = temp
+
+ try:
+ if response.status_code not in [202]:
+ raise HttpResponseError(response=response)
+ parts = response.parts()
+ if raise_on_any_failure:
+ parts = list(response.parts())
+ if any(p for p in parts if not 200 <= p.status_code < 300):
+ error = PartialBatchErrorException(
+ message="There is a partial failure in the batch operation.",
+ response=response, parts=parts
+ )
+ raise error
+ return iter(parts)
+ return parts
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+class TransportWrapper(HttpTransport):
+ """Wrapper class that ensures that an inner client created
+ by a `get_client` method does not close the outer transport for the parent
+ when used in a context manager.
+ """
+ def __init__(self, transport):
+ self._transport = transport
+
+ def send(self, request, **kwargs):
+ return self._transport.send(request, **kwargs)
+
+ def open(self):
+ pass
+
+ def close(self):
+ pass
+
+ def __enter__(self):
+ pass
+
+ def __exit__(self, *args): # pylint: disable=arguments-differ
+ pass
+
+
+def _format_shared_key_credential(account_name, credential):
+ if isinstance(credential, six.string_types):
+ if not account_name:
+ raise ValueError("Unable to determine account name for shared key credential.")
+ credential = {"account_name": account_name, "account_key": credential}
+ if isinstance(credential, dict):
+ if "account_name" not in credential:
+ raise ValueError("Shared key credential missing 'account_name")
+ if "account_key" not in credential:
+ raise ValueError("Shared key credential missing 'account_key")
+ return SharedKeyCredentialPolicy(**credential)
+ return credential
+
+
+def parse_connection_str(conn_str, credential, service):
+ conn_str = conn_str.rstrip(";")
+ conn_settings = [s.split("=", 1) for s in conn_str.split(";")]
+ if any(len(tup) != 2 for tup in conn_settings):
+ raise ValueError("Connection string is either blank or malformed.")
+ conn_settings = dict((key.upper(), val) for key, val in conn_settings)
+ endpoints = _SERVICE_PARAMS[service]
+ primary = None
+ secondary = None
+ if not credential:
+ try:
+ credential = {"account_name": conn_settings["ACCOUNTNAME"], "account_key": conn_settings["ACCOUNTKEY"]}
+ except KeyError:
+ credential = conn_settings.get("SHAREDACCESSSIGNATURE")
+ if endpoints["primary"] in conn_settings:
+ primary = conn_settings[endpoints["primary"]]
+ if endpoints["secondary"] in conn_settings:
+ secondary = conn_settings[endpoints["secondary"]]
+ else:
+ if endpoints["secondary"] in conn_settings:
+ raise ValueError("Connection string specifies only secondary endpoint.")
+ try:
+ primary = "{}://{}.{}.{}".format(
+ conn_settings["DEFAULTENDPOINTSPROTOCOL"],
+ conn_settings["ACCOUNTNAME"],
+ service,
+ conn_settings["ENDPOINTSUFFIX"],
+ )
+ secondary = "{}-secondary.{}.{}".format(
+ conn_settings["ACCOUNTNAME"], service, conn_settings["ENDPOINTSUFFIX"]
+ )
+ except KeyError:
+ pass
+
+ if not primary:
+ try:
+ primary = "https://{}.{}.{}".format(
+ conn_settings["ACCOUNTNAME"], service, conn_settings.get("ENDPOINTSUFFIX", SERVICE_HOST_BASE)
+ )
+ except KeyError:
+ raise ValueError("Connection string missing required connection details.")
+ if service == "dfs":
+ primary = primary.replace(".blob.", ".dfs.")
+ secondary = secondary.replace(".blob.", ".dfs.")
+ return primary, secondary, credential
+
+
+def create_configuration(**kwargs):
+ # type: (**Any) -> Configuration
+ config = Configuration(**kwargs)
+ config.headers_policy = StorageHeadersPolicy(**kwargs)
+ config.user_agent_policy = UserAgentPolicy(
+ sdk_moniker="storage-{}/{}".format(kwargs.pop('storage_sdk'), VERSION), **kwargs)
+ config.retry_policy = kwargs.get("retry_policy") or ExponentialRetry(**kwargs)
+ config.logging_policy = StorageLoggingPolicy(**kwargs)
+ config.proxy_policy = ProxyPolicy(**kwargs)
+
+ # Storage settings
+ config.max_single_put_size = kwargs.get("max_single_put_size", 64 * 1024 * 1024)
+ config.copy_polling_interval = 15
+
+ # Block blob uploads
+ config.max_block_size = kwargs.get("max_block_size", 4 * 1024 * 1024)
+ config.min_large_block_upload_threshold = kwargs.get("min_large_block_upload_threshold", 4 * 1024 * 1024 + 1)
+ config.use_byte_buffer = kwargs.get("use_byte_buffer", False)
+
+ # Page blob uploads
+ config.max_page_size = kwargs.get("max_page_size", 4 * 1024 * 1024)
+
+ # Datalake file uploads
+ config.min_large_chunk_upload_threshold = kwargs.get("min_large_chunk_upload_threshold", 100 * 1024 * 1024 + 1)
+
+ # Blob downloads
+ config.max_single_get_size = kwargs.get("max_single_get_size", 32 * 1024 * 1024)
+ config.max_chunk_get_size = kwargs.get("max_chunk_get_size", 4 * 1024 * 1024)
+
+ # File uploads
+ config.max_range_size = kwargs.get("max_range_size", 4 * 1024 * 1024)
+ return config
+
+
+def parse_query(query_str):
+ sas_values = QueryStringConstants.to_list()
+ parsed_query = {k: v[0] for k, v in parse_qs(query_str).items()}
+ sas_params = ["{}={}".format(k, quote(v, safe='')) for k, v in parsed_query.items() if k in sas_values]
+ sas_token = None
+ if sas_params:
+ sas_token = "&".join(sas_params)
+
+ snapshot = parsed_query.get("snapshot") or parsed_query.get("sharesnapshot")
+ return snapshot, sas_token
+
+
+def is_credential_sastoken(credential):
+ if not credential or not isinstance(credential, six.string_types):
+ return False
+
+ sas_values = QueryStringConstants.to_list()
+ parsed_query = parse_qs(credential.lstrip("?"))
+ if parsed_query and all([k in sas_values for k in parsed_query.keys()]):
+ return True
+ return False
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/base_client_async.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/base_client_async.py
new file mode 100644
index 00000000000..d8c5f430398
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/base_client_async.py
@@ -0,0 +1,191 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+from typing import ( # pylint: disable=unused-import
+ Union, Optional, Any, Iterable, Dict, List, Type, Tuple,
+ TYPE_CHECKING
+)
+import logging
+
+from azure.core.credentials import AzureSasCredential
+from azure.core.pipeline import AsyncPipeline
+from azure.core.async_paging import AsyncList
+from azure.core.exceptions import HttpResponseError
+from azure.core.pipeline.policies import (
+ AsyncRedirectPolicy,
+ AzureSasCredentialPolicy,
+ ContentDecodePolicy,
+ DistributedTracingPolicy,
+ HttpLoggingPolicy,
+)
+from azure.core.pipeline.transport import AsyncHttpTransport
+
+from .constants import CONNECTION_TIMEOUT, READ_TIMEOUT
+from .authentication import SharedKeyCredentialPolicy
+from .base_client import create_configuration
+from .policies import (
+ StorageContentValidation,
+ StorageHeadersPolicy,
+ StorageHosts,
+ StorageRequestHook,
+ QueueMessagePolicy
+)
+from .policies_async import AsyncStorageBearerTokenCredentialPolicy, AsyncStorageResponseHook
+
+from .response_handlers import process_storage_error, PartialBatchErrorException
+
+if TYPE_CHECKING:
+ from azure.core.pipeline import Pipeline
+ from azure.core.pipeline.transport import HttpRequest
+ from azure.core.configuration import Configuration
+_LOGGER = logging.getLogger(__name__)
+
+
+class AsyncStorageAccountHostsMixin(object):
+
+ def __enter__(self):
+ raise TypeError("Async client only supports 'async with'.")
+
+ def __exit__(self, *args):
+ pass
+
+ async def __aenter__(self):
+ await self._client.__aenter__()
+ return self
+
+ async def __aexit__(self, *args):
+ await self._client.__aexit__(*args)
+
+ async def close(self):
+ """ This method is to close the sockets opened by the client.
+ It need not be used when using with a context manager.
+ """
+ await self._client.close()
+
+ def _create_pipeline(self, credential, **kwargs):
+ # type: (Any, **Any) -> Tuple[Configuration, Pipeline]
+ self._credential_policy = None
+ if hasattr(credential, 'get_token'):
+ self._credential_policy = AsyncStorageBearerTokenCredentialPolicy(credential)
+ elif isinstance(credential, SharedKeyCredentialPolicy):
+ self._credential_policy = credential
+ elif isinstance(credential, AzureSasCredential):
+ self._credential_policy = AzureSasCredentialPolicy(credential)
+ elif credential is not None:
+ raise TypeError("Unsupported credential: {}".format(credential))
+ config = kwargs.get('_configuration') or create_configuration(**kwargs)
+ if kwargs.get('_pipeline'):
+ return config, kwargs['_pipeline']
+ config.transport = kwargs.get('transport') # type: ignore
+ kwargs.setdefault("connection_timeout", CONNECTION_TIMEOUT)
+ kwargs.setdefault("read_timeout", READ_TIMEOUT)
+ if not config.transport:
+ try:
+ from azure.core.pipeline.transport import AioHttpTransport
+ except ImportError:
+ raise ImportError("Unable to create async transport. Please check aiohttp is installed.")
+ config.transport = AioHttpTransport(**kwargs)
+ policies = [
+ QueueMessagePolicy(),
+ config.headers_policy,
+ config.proxy_policy,
+ config.user_agent_policy,
+ StorageContentValidation(),
+ StorageRequestHook(**kwargs),
+ self._credential_policy,
+ ContentDecodePolicy(response_encoding="utf-8"),
+ AsyncRedirectPolicy(**kwargs),
+ StorageHosts(hosts=self._hosts, **kwargs), # type: ignore
+ config.retry_policy,
+ config.logging_policy,
+ AsyncStorageResponseHook(**kwargs),
+ DistributedTracingPolicy(**kwargs),
+ HttpLoggingPolicy(**kwargs),
+ ]
+ if kwargs.get("_additional_pipeline_policies"):
+ policies = policies + kwargs.get("_additional_pipeline_policies")
+ return config, AsyncPipeline(config.transport, policies=policies)
+
+ async def _batch_send(
+ self,
+ *reqs, # type: HttpRequest
+ **kwargs
+ ):
+ """Given a series of request, do a Storage batch call.
+ """
+ # Pop it here, so requests doesn't feel bad about additional kwarg
+ raise_on_any_failure = kwargs.pop("raise_on_any_failure", True)
+ request = self._client._client.post( # pylint: disable=protected-access
+ url='{}://{}/{}?{}comp=batch{}{}'.format(
+ self.scheme,
+ self.primary_hostname,
+ kwargs.pop('path', ""),
+ kwargs.pop('restype', ""),
+ kwargs.pop('sas', ""),
+ kwargs.pop('timeout', "")
+ ),
+ headers={
+ 'x-ms-version': self.api_version
+ }
+ )
+
+ policies = [StorageHeadersPolicy()]
+ if self._credential_policy:
+ policies.append(self._credential_policy)
+
+ request.set_multipart_mixed(
+ *reqs,
+ policies=policies,
+ enforce_https=False
+ )
+
+ pipeline_response = await self._pipeline.run(
+ request, **kwargs
+ )
+ response = pipeline_response.http_response
+
+ try:
+ if response.status_code not in [202]:
+ raise HttpResponseError(response=response)
+ parts = response.parts() # Return an AsyncIterator
+ if raise_on_any_failure:
+ parts_list = []
+ async for part in parts:
+ parts_list.append(part)
+ if any(p for p in parts_list if not 200 <= p.status_code < 300):
+ error = PartialBatchErrorException(
+ message="There is a partial failure in the batch operation.",
+ response=response, parts=parts_list
+ )
+ raise error
+ return AsyncList(parts_list)
+ return parts
+ except HttpResponseError as error:
+ process_storage_error(error)
+
+
+class AsyncTransportWrapper(AsyncHttpTransport):
+ """Wrapper class that ensures that an inner client created
+ by a `get_client` method does not close the outer transport for the parent
+ when used in a context manager.
+ """
+ def __init__(self, async_transport):
+ self._transport = async_transport
+
+ async def send(self, request, **kwargs):
+ return await self._transport.send(request, **kwargs)
+
+ async def open(self):
+ pass
+
+ async def close(self):
+ pass
+
+ async def __aenter__(self):
+ pass
+
+ async def __aexit__(self, *args): # pylint: disable=arguments-differ
+ pass
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/constants.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/constants.py
new file mode 100644
index 00000000000..8a39d934e2a
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/constants.py
@@ -0,0 +1,28 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import sys
+from .._generated import AzureBlobStorage
+
+
+X_MS_VERSION = AzureBlobStorage(url="get_api_version")._config.version # pylint: disable=protected-access
+
+# Socket timeout in seconds
+CONNECTION_TIMEOUT = 20
+READ_TIMEOUT = 20
+
+# for python 3.5+, there was a change to the definition of the socket timeout (as far as socket.sendall is concerned)
+# The socket timeout is now the maximum total duration to send all data.
+if sys.version_info >= (3, 5):
+ # the timeout to connect is 20 seconds, and the read timeout is 80000 seconds
+ # the 80000 seconds was calculated with:
+ # 4000MB (max block size)/ 50KB/s (an arbitrarily chosen minimum upload speed)
+ READ_TIMEOUT = 80000
+
+DEFAULT_OAUTH_SCOPE = "/.default"
+STORAGE_OAUTH_SCOPE = "https://storage.azure.com/.default"
+
+SERVICE_HOST_BASE = 'core.windows.net'
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/encryption.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/encryption.py
new file mode 100644
index 00000000000..62607cc0cf8
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/encryption.py
@@ -0,0 +1,542 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import os
+from os import urandom
+from json import (
+ dumps,
+ loads,
+)
+from collections import OrderedDict
+
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives.ciphers import Cipher
+from cryptography.hazmat.primitives.ciphers.algorithms import AES
+from cryptography.hazmat.primitives.ciphers.modes import CBC
+from cryptography.hazmat.primitives.padding import PKCS7
+
+from azure.core.exceptions import HttpResponseError
+
+from .._version import VERSION
+from . import encode_base64, decode_base64_to_bytes
+
+
+_ENCRYPTION_PROTOCOL_V1 = '1.0'
+_ERROR_OBJECT_INVALID = \
+ '{0} does not define a complete interface. Value of {1} is either missing or invalid.'
+
+
+def _validate_not_none(param_name, param):
+ if param is None:
+ raise ValueError('{0} should not be None.'.format(param_name))
+
+
+def _validate_key_encryption_key_wrap(kek):
+ # Note that None is not callable and so will fail the second clause of each check.
+ if not hasattr(kek, 'wrap_key') or not callable(kek.wrap_key):
+ raise AttributeError(_ERROR_OBJECT_INVALID.format('key encryption key', 'wrap_key'))
+ if not hasattr(kek, 'get_kid') or not callable(kek.get_kid):
+ raise AttributeError(_ERROR_OBJECT_INVALID.format('key encryption key', 'get_kid'))
+ if not hasattr(kek, 'get_key_wrap_algorithm') or not callable(kek.get_key_wrap_algorithm):
+ raise AttributeError(_ERROR_OBJECT_INVALID.format('key encryption key', 'get_key_wrap_algorithm'))
+
+
+class _EncryptionAlgorithm(object):
+ '''
+ Specifies which client encryption algorithm is used.
+ '''
+ AES_CBC_256 = 'AES_CBC_256'
+
+
+class _WrappedContentKey:
+ '''
+ Represents the envelope key details stored on the service.
+ '''
+
+ def __init__(self, algorithm, encrypted_key, key_id):
+ '''
+ :param str algorithm:
+ The algorithm used for wrapping.
+ :param bytes encrypted_key:
+ The encrypted content-encryption-key.
+ :param str key_id:
+ The key-encryption-key identifier string.
+ '''
+
+ _validate_not_none('algorithm', algorithm)
+ _validate_not_none('encrypted_key', encrypted_key)
+ _validate_not_none('key_id', key_id)
+
+ self.algorithm = algorithm
+ self.encrypted_key = encrypted_key
+ self.key_id = key_id
+
+
+class _EncryptionAgent:
+ '''
+ Represents the encryption agent stored on the service.
+ It consists of the encryption protocol version and encryption algorithm used.
+ '''
+
+ def __init__(self, encryption_algorithm, protocol):
+ '''
+ :param _EncryptionAlgorithm encryption_algorithm:
+ The algorithm used for encrypting the message contents.
+ :param str protocol:
+ The protocol version used for encryption.
+ '''
+
+ _validate_not_none('encryption_algorithm', encryption_algorithm)
+ _validate_not_none('protocol', protocol)
+
+ self.encryption_algorithm = str(encryption_algorithm)
+ self.protocol = protocol
+
+
+class _EncryptionData:
+ '''
+ Represents the encryption data that is stored on the service.
+ '''
+
+ def __init__(self, content_encryption_IV, encryption_agent, wrapped_content_key,
+ key_wrapping_metadata):
+ '''
+ :param bytes content_encryption_IV:
+ The content encryption initialization vector.
+ :param _EncryptionAgent encryption_agent:
+ The encryption agent.
+ :param _WrappedContentKey wrapped_content_key:
+ An object that stores the wrapping algorithm, the key identifier,
+ and the encrypted key bytes.
+ :param dict key_wrapping_metadata:
+ A dict containing metadata related to the key wrapping.
+ '''
+
+ _validate_not_none('content_encryption_IV', content_encryption_IV)
+ _validate_not_none('encryption_agent', encryption_agent)
+ _validate_not_none('wrapped_content_key', wrapped_content_key)
+
+ self.content_encryption_IV = content_encryption_IV
+ self.encryption_agent = encryption_agent
+ self.wrapped_content_key = wrapped_content_key
+ self.key_wrapping_metadata = key_wrapping_metadata
+
+
+def _generate_encryption_data_dict(kek, cek, iv):
+ '''
+ Generates and returns the encryption metadata as a dict.
+
+ :param object kek: The key encryption key. See calling functions for more information.
+ :param bytes cek: The content encryption key.
+ :param bytes iv: The initialization vector.
+ :return: A dict containing all the encryption metadata.
+ :rtype: dict
+ '''
+ # Encrypt the cek.
+ wrapped_cek = kek.wrap_key(cek)
+
+ # Build the encryption_data dict.
+ # Use OrderedDict to comply with Java's ordering requirement.
+ wrapped_content_key = OrderedDict()
+ wrapped_content_key['KeyId'] = kek.get_kid()
+ wrapped_content_key['EncryptedKey'] = encode_base64(wrapped_cek)
+ wrapped_content_key['Algorithm'] = kek.get_key_wrap_algorithm()
+
+ encryption_agent = OrderedDict()
+ encryption_agent['Protocol'] = _ENCRYPTION_PROTOCOL_V1
+ encryption_agent['EncryptionAlgorithm'] = _EncryptionAlgorithm.AES_CBC_256
+
+ encryption_data_dict = OrderedDict()
+ encryption_data_dict['WrappedContentKey'] = wrapped_content_key
+ encryption_data_dict['EncryptionAgent'] = encryption_agent
+ encryption_data_dict['ContentEncryptionIV'] = encode_base64(iv)
+ encryption_data_dict['KeyWrappingMetadata'] = {'EncryptionLibrary': 'Python ' + VERSION}
+
+ return encryption_data_dict
+
+
+def _dict_to_encryption_data(encryption_data_dict):
+ '''
+ Converts the specified dictionary to an EncryptionData object for
+ eventual use in decryption.
+
+ :param dict encryption_data_dict:
+ The dictionary containing the encryption data.
+ :return: an _EncryptionData object built from the dictionary.
+ :rtype: _EncryptionData
+ '''
+ try:
+ if encryption_data_dict['EncryptionAgent']['Protocol'] != _ENCRYPTION_PROTOCOL_V1:
+ raise ValueError("Unsupported encryption version.")
+ except KeyError:
+ raise ValueError("Unsupported encryption version.")
+ wrapped_content_key = encryption_data_dict['WrappedContentKey']
+ wrapped_content_key = _WrappedContentKey(wrapped_content_key['Algorithm'],
+ decode_base64_to_bytes(wrapped_content_key['EncryptedKey']),
+ wrapped_content_key['KeyId'])
+
+ encryption_agent = encryption_data_dict['EncryptionAgent']
+ encryption_agent = _EncryptionAgent(encryption_agent['EncryptionAlgorithm'],
+ encryption_agent['Protocol'])
+
+ if 'KeyWrappingMetadata' in encryption_data_dict:
+ key_wrapping_metadata = encryption_data_dict['KeyWrappingMetadata']
+ else:
+ key_wrapping_metadata = None
+
+ encryption_data = _EncryptionData(decode_base64_to_bytes(encryption_data_dict['ContentEncryptionIV']),
+ encryption_agent,
+ wrapped_content_key,
+ key_wrapping_metadata)
+
+ return encryption_data
+
+
+def _generate_AES_CBC_cipher(cek, iv):
+ '''
+ Generates and returns an encryption cipher for AES CBC using the given cek and iv.
+
+ :param bytes[] cek: The content encryption key for the cipher.
+ :param bytes[] iv: The initialization vector for the cipher.
+ :return: A cipher for encrypting in AES256 CBC.
+ :rtype: ~cryptography.hazmat.primitives.ciphers.Cipher
+ '''
+
+ backend = default_backend()
+ algorithm = AES(cek)
+ mode = CBC(iv)
+ return Cipher(algorithm, mode, backend)
+
+
+def _validate_and_unwrap_cek(encryption_data, key_encryption_key=None, key_resolver=None):
+ '''
+ Extracts and returns the content_encryption_key stored in the encryption_data object
+ and performs necessary validation on all parameters.
+ :param _EncryptionData encryption_data:
+ The encryption metadata of the retrieved value.
+ :param obj key_encryption_key:
+ The key_encryption_key used to unwrap the cek. Please refer to high-level service object
+ instance variables for more details.
+ :param func key_resolver:
+ A function used that, given a key_id, will return a key_encryption_key. Please refer
+ to high-level service object instance variables for more details.
+ :return: the content_encryption_key stored in the encryption_data object.
+ :rtype: bytes[]
+ '''
+
+ _validate_not_none('content_encryption_IV', encryption_data.content_encryption_IV)
+ _validate_not_none('encrypted_key', encryption_data.wrapped_content_key.encrypted_key)
+
+ if _ENCRYPTION_PROTOCOL_V1 != encryption_data.encryption_agent.protocol:
+ raise ValueError('Encryption version is not supported.')
+
+ content_encryption_key = None
+
+ # If the resolver exists, give priority to the key it finds.
+ if key_resolver is not None:
+ key_encryption_key = key_resolver(encryption_data.wrapped_content_key.key_id)
+
+ _validate_not_none('key_encryption_key', key_encryption_key)
+ if not hasattr(key_encryption_key, 'get_kid') or not callable(key_encryption_key.get_kid):
+ raise AttributeError(_ERROR_OBJECT_INVALID.format('key encryption key', 'get_kid'))
+ if not hasattr(key_encryption_key, 'unwrap_key') or not callable(key_encryption_key.unwrap_key):
+ raise AttributeError(_ERROR_OBJECT_INVALID.format('key encryption key', 'unwrap_key'))
+ if encryption_data.wrapped_content_key.key_id != key_encryption_key.get_kid():
+ raise ValueError('Provided or resolved key-encryption-key does not match the id of key used to encrypt.')
+ # Will throw an exception if the specified algorithm is not supported.
+ content_encryption_key = key_encryption_key.unwrap_key(encryption_data.wrapped_content_key.encrypted_key,
+ encryption_data.wrapped_content_key.algorithm)
+ _validate_not_none('content_encryption_key', content_encryption_key)
+
+ return content_encryption_key
+
+
+def _decrypt_message(message, encryption_data, key_encryption_key=None, resolver=None):
+ '''
+ Decrypts the given ciphertext using AES256 in CBC mode with 128 bit padding.
+ Unwraps the content-encryption-key using the user-provided or resolved key-encryption-key (kek).
+ Returns the original plaintex.
+
+ :param str message:
+ The ciphertext to be decrypted.
+ :param _EncryptionData encryption_data:
+ The metadata associated with this ciphertext.
+ :param object key_encryption_key:
+ The user-provided key-encryption-key. Must implement the following methods:
+ unwrap_key(key, algorithm)
+ - returns the unwrapped form of the specified symmetric key using the string-specified algorithm.
+ get_kid()
+ - returns a string key id for this key-encryption-key.
+ :param function resolver(kid):
+ The user-provided key resolver. Uses the kid string to return a key-encryption-key
+ implementing the interface defined above.
+ :return: The decrypted plaintext.
+ :rtype: str
+ '''
+ _validate_not_none('message', message)
+ content_encryption_key = _validate_and_unwrap_cek(encryption_data, key_encryption_key, resolver)
+
+ if _EncryptionAlgorithm.AES_CBC_256 != encryption_data.encryption_agent.encryption_algorithm:
+ raise ValueError('Specified encryption algorithm is not supported.')
+
+ cipher = _generate_AES_CBC_cipher(content_encryption_key, encryption_data.content_encryption_IV)
+
+ # decrypt data
+ decrypted_data = message
+ decryptor = cipher.decryptor()
+ decrypted_data = (decryptor.update(decrypted_data) + decryptor.finalize())
+
+ # unpad data
+ unpadder = PKCS7(128).unpadder()
+ decrypted_data = (unpadder.update(decrypted_data) + unpadder.finalize())
+
+ return decrypted_data
+
+
+def encrypt_blob(blob, key_encryption_key):
+ '''
+ Encrypts the given blob using AES256 in CBC mode with 128 bit padding.
+ Wraps the generated content-encryption-key using the user-provided key-encryption-key (kek).
+ Returns a json-formatted string containing the encryption metadata. This method should
+ only be used when a blob is small enough for single shot upload. Encrypting larger blobs
+ is done as a part of the upload_data_chunks method.
+
+ :param bytes blob:
+ The blob to be encrypted.
+ :param object key_encryption_key:
+ The user-provided key-encryption-key. Must implement the following methods:
+ wrap_key(key)--wraps the specified key using an algorithm of the user's choice.
+ get_key_wrap_algorithm()--returns the algorithm used to wrap the specified symmetric key.
+ get_kid()--returns a string key id for this key-encryption-key.
+ :return: A tuple of json-formatted string containing the encryption metadata and the encrypted blob data.
+ :rtype: (str, bytes)
+ '''
+
+ _validate_not_none('blob', blob)
+ _validate_not_none('key_encryption_key', key_encryption_key)
+ _validate_key_encryption_key_wrap(key_encryption_key)
+
+ # AES256 uses 256 bit (32 byte) keys and always with 16 byte blocks
+ content_encryption_key = urandom(32)
+ initialization_vector = urandom(16)
+
+ cipher = _generate_AES_CBC_cipher(content_encryption_key, initialization_vector)
+
+ # PKCS7 with 16 byte blocks ensures compatibility with AES.
+ padder = PKCS7(128).padder()
+ padded_data = padder.update(blob) + padder.finalize()
+
+ # Encrypt the data.
+ encryptor = cipher.encryptor()
+ encrypted_data = encryptor.update(padded_data) + encryptor.finalize()
+ encryption_data = _generate_encryption_data_dict(key_encryption_key, content_encryption_key,
+ initialization_vector)
+ encryption_data['EncryptionMode'] = 'FullBlob'
+
+ return dumps(encryption_data), encrypted_data
+
+
+def generate_blob_encryption_data(key_encryption_key):
+ '''
+ Generates the encryption_metadata for the blob.
+
+ :param bytes key_encryption_key:
+ The key-encryption-key used to wrap the cek associate with this blob.
+ :return: A tuple containing the cek and iv for this blob as well as the
+ serialized encryption metadata for the blob.
+ :rtype: (bytes, bytes, str)
+ '''
+ encryption_data = None
+ content_encryption_key = None
+ initialization_vector = None
+ if key_encryption_key:
+ _validate_key_encryption_key_wrap(key_encryption_key)
+ content_encryption_key = urandom(32)
+ initialization_vector = urandom(16)
+ encryption_data = _generate_encryption_data_dict(key_encryption_key,
+ content_encryption_key,
+ initialization_vector)
+ encryption_data['EncryptionMode'] = 'FullBlob'
+ encryption_data = dumps(encryption_data)
+
+ return content_encryption_key, initialization_vector, encryption_data
+
+
+def decrypt_blob(require_encryption, key_encryption_key, key_resolver,
+ content, start_offset, end_offset, response_headers):
+ '''
+ Decrypts the given blob contents and returns only the requested range.
+
+ :param bool require_encryption:
+ Whether or not the calling blob service requires objects to be decrypted.
+ :param object key_encryption_key:
+ The user-provided key-encryption-key. Must implement the following methods:
+ wrap_key(key)--wraps the specified key using an algorithm of the user's choice.
+ get_key_wrap_algorithm()--returns the algorithm used to wrap the specified symmetric key.
+ get_kid()--returns a string key id for this key-encryption-key.
+ :param key_resolver(kid):
+ The user-provided key resolver. Uses the kid string to return a key-encryption-key
+ implementing the interface defined above.
+ :return: The decrypted blob content.
+ :rtype: bytes
+ '''
+ try:
+ encryption_data = _dict_to_encryption_data(loads(response_headers['x-ms-meta-encryptiondata']))
+ except: # pylint: disable=bare-except
+ if require_encryption:
+ raise ValueError(
+ 'Encryption required, but received data does not contain appropriate metatadata.' + \
+ 'Data was either not encrypted or metadata has been lost.')
+
+ return content
+
+ if encryption_data.encryption_agent.encryption_algorithm != _EncryptionAlgorithm.AES_CBC_256:
+ raise ValueError('Specified encryption algorithm is not supported.')
+
+ blob_type = response_headers['x-ms-blob-type']
+
+ iv = None
+ unpad = False
+ if 'content-range' in response_headers:
+ content_range = response_headers['content-range']
+ # Format: 'bytes x-y/size'
+
+ # Ignore the word 'bytes'
+ content_range = content_range.split(' ')
+
+ content_range = content_range[1].split('-')
+ content_range = content_range[1].split('/')
+ end_range = int(content_range[0])
+ blob_size = int(content_range[1])
+
+ if start_offset >= 16:
+ iv = content[:16]
+ content = content[16:]
+ start_offset -= 16
+ else:
+ iv = encryption_data.content_encryption_IV
+
+ if end_range == blob_size - 1:
+ unpad = True
+ else:
+ unpad = True
+ iv = encryption_data.content_encryption_IV
+
+ if blob_type == 'PageBlob':
+ unpad = False
+
+ content_encryption_key = _validate_and_unwrap_cek(encryption_data, key_encryption_key, key_resolver)
+ cipher = _generate_AES_CBC_cipher(content_encryption_key, iv)
+ decryptor = cipher.decryptor()
+
+ content = decryptor.update(content) + decryptor.finalize()
+ if unpad:
+ unpadder = PKCS7(128).unpadder()
+ content = unpadder.update(content) + unpadder.finalize()
+
+ return content[start_offset: len(content) - end_offset]
+
+
+def get_blob_encryptor_and_padder(cek, iv, should_pad):
+ encryptor = None
+ padder = None
+
+ if cek is not None and iv is not None:
+ cipher = _generate_AES_CBC_cipher(cek, iv)
+ encryptor = cipher.encryptor()
+ padder = PKCS7(128).padder() if should_pad else None
+
+ return encryptor, padder
+
+
+def encrypt_queue_message(message, key_encryption_key):
+ '''
+ Encrypts the given plain text message using AES256 in CBC mode with 128 bit padding.
+ Wraps the generated content-encryption-key using the user-provided key-encryption-key (kek).
+ Returns a json-formatted string containing the encrypted message and the encryption metadata.
+
+ :param object message:
+ The plain text messge to be encrypted.
+ :param object key_encryption_key:
+ The user-provided key-encryption-key. Must implement the following methods:
+ wrap_key(key)--wraps the specified key using an algorithm of the user's choice.
+ get_key_wrap_algorithm()--returns the algorithm used to wrap the specified symmetric key.
+ get_kid()--returns a string key id for this key-encryption-key.
+ :return: A json-formatted string containing the encrypted message and the encryption metadata.
+ :rtype: str
+ '''
+
+ _validate_not_none('message', message)
+ _validate_not_none('key_encryption_key', key_encryption_key)
+ _validate_key_encryption_key_wrap(key_encryption_key)
+
+ # AES256 uses 256 bit (32 byte) keys and always with 16 byte blocks
+ content_encryption_key = os.urandom(32)
+ initialization_vector = os.urandom(16)
+
+ # Queue encoding functions all return unicode strings, and encryption should
+ # operate on binary strings.
+ message = message.encode('utf-8')
+
+ cipher = _generate_AES_CBC_cipher(content_encryption_key, initialization_vector)
+
+ # PKCS7 with 16 byte blocks ensures compatibility with AES.
+ padder = PKCS7(128).padder()
+ padded_data = padder.update(message) + padder.finalize()
+
+ # Encrypt the data.
+ encryptor = cipher.encryptor()
+ encrypted_data = encryptor.update(padded_data) + encryptor.finalize()
+
+ # Build the dictionary structure.
+ queue_message = {'EncryptedMessageContents': encode_base64(encrypted_data),
+ 'EncryptionData': _generate_encryption_data_dict(key_encryption_key,
+ content_encryption_key,
+ initialization_vector)}
+
+ return dumps(queue_message)
+
+
+def decrypt_queue_message(message, response, require_encryption, key_encryption_key, resolver):
+ '''
+ Returns the decrypted message contents from an EncryptedQueueMessage.
+ If no encryption metadata is present, will return the unaltered message.
+ :param str message:
+ The JSON formatted QueueEncryptedMessage contents with all associated metadata.
+ :param bool require_encryption:
+ If set, will enforce that the retrieved messages are encrypted and decrypt them.
+ :param object key_encryption_key:
+ The user-provided key-encryption-key. Must implement the following methods:
+ unwrap_key(key, algorithm)
+ - returns the unwrapped form of the specified symmetric key usingthe string-specified algorithm.
+ get_kid()
+ - returns a string key id for this key-encryption-key.
+ :param function resolver(kid):
+ The user-provided key resolver. Uses the kid string to return a key-encryption-key
+ implementing the interface defined above.
+ :return: The plain text message from the queue message.
+ :rtype: str
+ '''
+
+ try:
+ message = loads(message)
+
+ encryption_data = _dict_to_encryption_data(message['EncryptionData'])
+ decoded_data = decode_base64_to_bytes(message['EncryptedMessageContents'])
+ except (KeyError, ValueError):
+ # Message was not json formatted and so was not encrypted
+ # or the user provided a json formatted message.
+ if require_encryption:
+ raise ValueError('Message was not encrypted.')
+
+ return message
+ try:
+ return _decrypt_message(decoded_data, encryption_data, key_encryption_key, resolver).decode('utf-8')
+ except Exception as error:
+ raise HttpResponseError(
+ message="Decryption failed.",
+ response=response,
+ error=error)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/models.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/models.py
new file mode 100644
index 00000000000..22e7b7522ae
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/models.py
@@ -0,0 +1,480 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=too-many-instance-attributes
+from enum import Enum
+
+
+def get_enum_value(value):
+ if value is None or value in ["None", ""]:
+ return None
+ try:
+ return value.value
+ except AttributeError:
+ return value
+
+
+class StorageErrorCode(str, Enum):
+
+ # Generic storage values
+ account_already_exists = "AccountAlreadyExists"
+ account_being_created = "AccountBeingCreated"
+ account_is_disabled = "AccountIsDisabled"
+ authentication_failed = "AuthenticationFailed"
+ authorization_failure = "AuthorizationFailure"
+ no_authentication_information = "NoAuthenticationInformation"
+ condition_headers_not_supported = "ConditionHeadersNotSupported"
+ condition_not_met = "ConditionNotMet"
+ empty_metadata_key = "EmptyMetadataKey"
+ insufficient_account_permissions = "InsufficientAccountPermissions"
+ internal_error = "InternalError"
+ invalid_authentication_info = "InvalidAuthenticationInfo"
+ invalid_header_value = "InvalidHeaderValue"
+ invalid_http_verb = "InvalidHttpVerb"
+ invalid_input = "InvalidInput"
+ invalid_md5 = "InvalidMd5"
+ invalid_metadata = "InvalidMetadata"
+ invalid_query_parameter_value = "InvalidQueryParameterValue"
+ invalid_range = "InvalidRange"
+ invalid_resource_name = "InvalidResourceName"
+ invalid_uri = "InvalidUri"
+ invalid_xml_document = "InvalidXmlDocument"
+ invalid_xml_node_value = "InvalidXmlNodeValue"
+ md5_mismatch = "Md5Mismatch"
+ metadata_too_large = "MetadataTooLarge"
+ missing_content_length_header = "MissingContentLengthHeader"
+ missing_required_query_parameter = "MissingRequiredQueryParameter"
+ missing_required_header = "MissingRequiredHeader"
+ missing_required_xml_node = "MissingRequiredXmlNode"
+ multiple_condition_headers_not_supported = "MultipleConditionHeadersNotSupported"
+ operation_timed_out = "OperationTimedOut"
+ out_of_range_input = "OutOfRangeInput"
+ out_of_range_query_parameter_value = "OutOfRangeQueryParameterValue"
+ request_body_too_large = "RequestBodyTooLarge"
+ resource_type_mismatch = "ResourceTypeMismatch"
+ request_url_failed_to_parse = "RequestUrlFailedToParse"
+ resource_already_exists = "ResourceAlreadyExists"
+ resource_not_found = "ResourceNotFound"
+ server_busy = "ServerBusy"
+ unsupported_header = "UnsupportedHeader"
+ unsupported_xml_node = "UnsupportedXmlNode"
+ unsupported_query_parameter = "UnsupportedQueryParameter"
+ unsupported_http_verb = "UnsupportedHttpVerb"
+
+ # Blob values
+ append_position_condition_not_met = "AppendPositionConditionNotMet"
+ blob_already_exists = "BlobAlreadyExists"
+ blob_not_found = "BlobNotFound"
+ blob_overwritten = "BlobOverwritten"
+ blob_tier_inadequate_for_content_length = "BlobTierInadequateForContentLength"
+ block_count_exceeds_limit = "BlockCountExceedsLimit"
+ block_list_too_long = "BlockListTooLong"
+ cannot_change_to_lower_tier = "CannotChangeToLowerTier"
+ cannot_verify_copy_source = "CannotVerifyCopySource"
+ container_already_exists = "ContainerAlreadyExists"
+ container_being_deleted = "ContainerBeingDeleted"
+ container_disabled = "ContainerDisabled"
+ container_not_found = "ContainerNotFound"
+ content_length_larger_than_tier_limit = "ContentLengthLargerThanTierLimit"
+ copy_across_accounts_not_supported = "CopyAcrossAccountsNotSupported"
+ copy_id_mismatch = "CopyIdMismatch"
+ feature_version_mismatch = "FeatureVersionMismatch"
+ incremental_copy_blob_mismatch = "IncrementalCopyBlobMismatch"
+ incremental_copy_of_eralier_version_snapshot_not_allowed = "IncrementalCopyOfEralierVersionSnapshotNotAllowed"
+ incremental_copy_source_must_be_snapshot = "IncrementalCopySourceMustBeSnapshot"
+ infinite_lease_duration_required = "InfiniteLeaseDurationRequired"
+ invalid_blob_or_block = "InvalidBlobOrBlock"
+ invalid_blob_tier = "InvalidBlobTier"
+ invalid_blob_type = "InvalidBlobType"
+ invalid_block_id = "InvalidBlockId"
+ invalid_block_list = "InvalidBlockList"
+ invalid_operation = "InvalidOperation"
+ invalid_page_range = "InvalidPageRange"
+ invalid_source_blob_type = "InvalidSourceBlobType"
+ invalid_source_blob_url = "InvalidSourceBlobUrl"
+ invalid_version_for_page_blob_operation = "InvalidVersionForPageBlobOperation"
+ lease_already_present = "LeaseAlreadyPresent"
+ lease_already_broken = "LeaseAlreadyBroken"
+ lease_id_mismatch_with_blob_operation = "LeaseIdMismatchWithBlobOperation"
+ lease_id_mismatch_with_container_operation = "LeaseIdMismatchWithContainerOperation"
+ lease_id_mismatch_with_lease_operation = "LeaseIdMismatchWithLeaseOperation"
+ lease_id_missing = "LeaseIdMissing"
+ lease_is_breaking_and_cannot_be_acquired = "LeaseIsBreakingAndCannotBeAcquired"
+ lease_is_breaking_and_cannot_be_changed = "LeaseIsBreakingAndCannotBeChanged"
+ lease_is_broken_and_cannot_be_renewed = "LeaseIsBrokenAndCannotBeRenewed"
+ lease_lost = "LeaseLost"
+ lease_not_present_with_blob_operation = "LeaseNotPresentWithBlobOperation"
+ lease_not_present_with_container_operation = "LeaseNotPresentWithContainerOperation"
+ lease_not_present_with_lease_operation = "LeaseNotPresentWithLeaseOperation"
+ max_blob_size_condition_not_met = "MaxBlobSizeConditionNotMet"
+ no_pending_copy_operation = "NoPendingCopyOperation"
+ operation_not_allowed_on_incremental_copy_blob = "OperationNotAllowedOnIncrementalCopyBlob"
+ pending_copy_operation = "PendingCopyOperation"
+ previous_snapshot_cannot_be_newer = "PreviousSnapshotCannotBeNewer"
+ previous_snapshot_not_found = "PreviousSnapshotNotFound"
+ previous_snapshot_operation_not_supported = "PreviousSnapshotOperationNotSupported"
+ sequence_number_condition_not_met = "SequenceNumberConditionNotMet"
+ sequence_number_increment_too_large = "SequenceNumberIncrementTooLarge"
+ snapshot_count_exceeded = "SnapshotCountExceeded"
+ snaphot_operation_rate_exceeded = "SnaphotOperationRateExceeded"
+ snapshots_present = "SnapshotsPresent"
+ source_condition_not_met = "SourceConditionNotMet"
+ system_in_use = "SystemInUse"
+ target_condition_not_met = "TargetConditionNotMet"
+ unauthorized_blob_overwrite = "UnauthorizedBlobOverwrite"
+ blob_being_rehydrated = "BlobBeingRehydrated"
+ blob_archived = "BlobArchived"
+ blob_not_archived = "BlobNotArchived"
+
+ # Queue values
+ invalid_marker = "InvalidMarker"
+ message_not_found = "MessageNotFound"
+ message_too_large = "MessageTooLarge"
+ pop_receipt_mismatch = "PopReceiptMismatch"
+ queue_already_exists = "QueueAlreadyExists"
+ queue_being_deleted = "QueueBeingDeleted"
+ queue_disabled = "QueueDisabled"
+ queue_not_empty = "QueueNotEmpty"
+ queue_not_found = "QueueNotFound"
+
+ # File values
+ cannot_delete_file_or_directory = "CannotDeleteFileOrDirectory"
+ client_cache_flush_delay = "ClientCacheFlushDelay"
+ delete_pending = "DeletePending"
+ directory_not_empty = "DirectoryNotEmpty"
+ file_lock_conflict = "FileLockConflict"
+ invalid_file_or_directory_path_name = "InvalidFileOrDirectoryPathName"
+ parent_not_found = "ParentNotFound"
+ read_only_attribute = "ReadOnlyAttribute"
+ share_already_exists = "ShareAlreadyExists"
+ share_being_deleted = "ShareBeingDeleted"
+ share_disabled = "ShareDisabled"
+ share_not_found = "ShareNotFound"
+ sharing_violation = "SharingViolation"
+ share_snapshot_in_progress = "ShareSnapshotInProgress"
+ share_snapshot_count_exceeded = "ShareSnapshotCountExceeded"
+ share_snapshot_operation_not_supported = "ShareSnapshotOperationNotSupported"
+ share_has_snapshots = "ShareHasSnapshots"
+ container_quota_downgrade_not_allowed = "ContainerQuotaDowngradeNotAllowed"
+
+ # DataLake values
+ content_length_must_be_zero = 'ContentLengthMustBeZero'
+ path_already_exists = 'PathAlreadyExists'
+ invalid_flush_position = 'InvalidFlushPosition'
+ invalid_property_name = 'InvalidPropertyName'
+ invalid_source_uri = 'InvalidSourceUri'
+ unsupported_rest_version = 'UnsupportedRestVersion'
+ file_system_not_found = 'FilesystemNotFound'
+ path_not_found = 'PathNotFound'
+ rename_destination_parent_path_not_found = 'RenameDestinationParentPathNotFound'
+ source_path_not_found = 'SourcePathNotFound'
+ destination_path_is_being_deleted = 'DestinationPathIsBeingDeleted'
+ file_system_already_exists = 'FilesystemAlreadyExists'
+ file_system_being_deleted = 'FilesystemBeingDeleted'
+ invalid_destination_path = 'InvalidDestinationPath'
+ invalid_rename_source_path = 'InvalidRenameSourcePath'
+ invalid_source_or_destination_resource_type = 'InvalidSourceOrDestinationResourceType'
+ lease_is_already_broken = 'LeaseIsAlreadyBroken'
+ lease_name_mismatch = 'LeaseNameMismatch'
+ path_conflict = 'PathConflict'
+ source_path_is_being_deleted = 'SourcePathIsBeingDeleted'
+
+
+class DictMixin(object):
+
+ def __setitem__(self, key, item):
+ self.__dict__[key] = item
+
+ def __getitem__(self, key):
+ return self.__dict__[key]
+
+ def __repr__(self):
+ return str(self)
+
+ def __len__(self):
+ return len(self.keys())
+
+ def __delitem__(self, key):
+ self.__dict__[key] = None
+
+ def __eq__(self, other):
+ """Compare objects by comparing all attributes."""
+ if isinstance(other, self.__class__):
+ return self.__dict__ == other.__dict__
+ return False
+
+ def __ne__(self, other):
+ """Compare objects by comparing all attributes."""
+ return not self.__eq__(other)
+
+ def __str__(self):
+ return str({k: v for k, v in self.__dict__.items() if not k.startswith('_')})
+
+ def has_key(self, k):
+ return k in self.__dict__
+
+ def update(self, *args, **kwargs):
+ return self.__dict__.update(*args, **kwargs)
+
+ def keys(self):
+ return [k for k in self.__dict__ if not k.startswith('_')]
+
+ def values(self):
+ return [v for k, v in self.__dict__.items() if not k.startswith('_')]
+
+ def items(self):
+ return [(k, v) for k, v in self.__dict__.items() if not k.startswith('_')]
+
+ def get(self, key, default=None):
+ if key in self.__dict__:
+ return self.__dict__[key]
+ return default
+
+
+class LocationMode(object):
+ """
+ Specifies the location the request should be sent to. This mode only applies
+ for RA-GRS accounts which allow secondary read access. All other account types
+ must use PRIMARY.
+ """
+
+ PRIMARY = 'primary' #: Requests should be sent to the primary location.
+ SECONDARY = 'secondary' #: Requests should be sent to the secondary location, if possible.
+
+
+class ResourceTypes(object):
+ """
+ Specifies the resource types that are accessible with the account SAS.
+
+ :param bool service:
+ Access to service-level APIs (e.g., Get/Set Service Properties,
+ Get Service Stats, List Containers/Queues/Shares)
+ :param bool container:
+ Access to container-level APIs (e.g., Create/Delete Container,
+ Create/Delete Queue, Create/Delete Share,
+ List Blobs/Files and Directories)
+ :param bool object:
+ Access to object-level APIs for blobs, queue messages, and
+ files(e.g. Put Blob, Query Entity, Get Messages, Create File, etc.)
+ """
+
+ def __init__(self, service=False, container=False, object=False): # pylint: disable=redefined-builtin
+ self.service = service
+ self.container = container
+ self.object = object
+ self._str = (('s' if self.service else '') +
+ ('c' if self.container else '') +
+ ('o' if self.object else ''))
+
+ def __str__(self):
+ return self._str
+
+ @classmethod
+ def from_string(cls, string):
+ """Create a ResourceTypes from a string.
+
+ To specify service, container, or object you need only to
+ include the first letter of the word in the string. E.g. service and container,
+ you would provide a string "sc".
+
+ :param str string: Specify service, container, or object in
+ in the string with the first letter of the word.
+ :return: A ResourceTypes object
+ :rtype: ~azure.storage.blob.ResourceTypes
+ """
+ res_service = 's' in string
+ res_container = 'c' in string
+ res_object = 'o' in string
+
+ parsed = cls(res_service, res_container, res_object)
+ parsed._str = string # pylint: disable = protected-access
+ return parsed
+
+
+class AccountSasPermissions(object):
+ """
+ :class:`~ResourceTypes` class to be used with generate_account_sas
+ function and for the AccessPolicies used with set_*_acl. There are two types of
+ SAS which may be used to grant resource access. One is to grant access to a
+ specific resource (resource-specific). Another is to grant access to the
+ entire service for a specific account and allow certain operations based on
+ perms found here.
+
+ :param bool read:
+ Valid for all signed resources types (Service, Container, and Object).
+ Permits read permissions to the specified resource type.
+ :param bool write:
+ Valid for all signed resources types (Service, Container, and Object).
+ Permits write permissions to the specified resource type.
+ :param bool delete:
+ Valid for Container and Object resource types, except for queue messages.
+ :param bool delete_previous_version:
+ Delete the previous blob version for the versioning enabled storage account.
+ :param bool list:
+ Valid for Service and Container resource types only.
+ :param bool add:
+ Valid for the following Object resource types only: queue messages, and append blobs.
+ :param bool create:
+ Valid for the following Object resource types only: blobs and files.
+ Users can create new blobs or files, but may not overwrite existing
+ blobs or files.
+ :param bool update:
+ Valid for the following Object resource types only: queue messages.
+ :param bool process:
+ Valid for the following Object resource type only: queue messages.
+ :keyword bool tag:
+ To enable set or get tags on the blobs in the container.
+ :keyword bool filter_by_tags:
+ To enable get blobs by tags, this should be used together with list permission.
+ :keyword bool set_immutability_policy:
+ To enable operations related to set/delete immutability policy.
+ To get immutability policy, you just need read permission.
+ :keyword bool permanent_delete:
+ To enable permanent delete on the blob is permitted.
+ Valid for Object resource type of Blob only.
+ """
+ def __init__(self, read=False, write=False, delete=False,
+ list=False, # pylint: disable=redefined-builtin
+ add=False, create=False, update=False, process=False, delete_previous_version=False, **kwargs):
+ self.read = read
+ self.write = write
+ self.delete = delete
+ self.delete_previous_version = delete_previous_version
+ self.permanent_delete = kwargs.pop('permanent_delete', False)
+ self.list = list
+ self.add = add
+ self.create = create
+ self.update = update
+ self.process = process
+ self.tag = kwargs.pop('tag', False)
+ self.filter_by_tags = kwargs.pop('filter_by_tags', False)
+ self.set_immutability_policy = kwargs.pop('set_immutability_policy', False)
+ self._str = (('r' if self.read else '') +
+ ('w' if self.write else '') +
+ ('d' if self.delete else '') +
+ ('x' if self.delete_previous_version else '') +
+ ('y' if self.permanent_delete else '') +
+ ('l' if self.list else '') +
+ ('a' if self.add else '') +
+ ('c' if self.create else '') +
+ ('u' if self.update else '') +
+ ('p' if self.process else '') +
+ ('f' if self.filter_by_tags else '') +
+ ('t' if self.tag else '') +
+ ('i' if self.set_immutability_policy else '')
+ )
+
+ def __str__(self):
+ return self._str
+
+ @classmethod
+ def from_string(cls, permission):
+ """Create AccountSasPermissions from a string.
+
+ To specify read, write, delete, etc. permissions you need only to
+ include the first letter of the word in the string. E.g. for read and write
+ permissions you would provide a string "rw".
+
+ :param str permission: Specify permissions in
+ the string with the first letter of the word.
+ :return: An AccountSasPermissions object
+ :rtype: ~azure.storage.blob.AccountSasPermissions
+ """
+ p_read = 'r' in permission
+ p_write = 'w' in permission
+ p_delete = 'd' in permission
+ p_delete_previous_version = 'x' in permission
+ p_permanent_delete = 'y' in permission
+ p_list = 'l' in permission
+ p_add = 'a' in permission
+ p_create = 'c' in permission
+ p_update = 'u' in permission
+ p_process = 'p' in permission
+ p_tag = 't' in permission
+ p_filter_by_tags = 'f' in permission
+ p_set_immutability_policy = 'i' in permission
+ parsed = cls(read=p_read, write=p_write, delete=p_delete, delete_previous_version=p_delete_previous_version,
+ list=p_list, add=p_add, create=p_create, update=p_update, process=p_process, tag=p_tag,
+ filter_by_tags=p_filter_by_tags, set_immutability_policy=p_set_immutability_policy,
+ permanent_delete=p_permanent_delete)
+
+ return parsed
+
+
+class Services(object):
+ """Specifies the services accessible with the account SAS.
+
+ :param bool blob:
+ Access for the `~azure.storage.blob.BlobServiceClient`
+ :param bool queue:
+ Access for the `~azure.storage.queue.QueueServiceClient`
+ :param bool fileshare:
+ Access for the `~azure.storage.fileshare.ShareServiceClient`
+ """
+
+ def __init__(self, blob=False, queue=False, fileshare=False):
+ self.blob = blob
+ self.queue = queue
+ self.fileshare = fileshare
+ self._str = (('b' if self.blob else '') +
+ ('q' if self.queue else '') +
+ ('f' if self.fileshare else ''))
+
+ def __str__(self):
+ return self._str
+
+ @classmethod
+ def from_string(cls, string):
+ """Create Services from a string.
+
+ To specify blob, queue, or file you need only to
+ include the first letter of the word in the string. E.g. for blob and queue
+ you would provide a string "bq".
+
+ :param str string: Specify blob, queue, or file in
+ in the string with the first letter of the word.
+ :return: A Services object
+ :rtype: ~azure.storage.blob.Services
+ """
+ res_blob = 'b' in string
+ res_queue = 'q' in string
+ res_file = 'f' in string
+
+ parsed = cls(res_blob, res_queue, res_file)
+ parsed._str = string # pylint: disable = protected-access
+ return parsed
+
+
+class UserDelegationKey(object):
+ """
+ Represents a user delegation key, provided to the user by Azure Storage
+ based on their Azure Active Directory access token.
+
+ The fields are saved as simple strings since the user does not have to interact with this object;
+ to generate an identify SAS, the user can simply pass it to the right API.
+
+ :ivar str signed_oid:
+ Object ID of this token.
+ :ivar str signed_tid:
+ Tenant ID of the tenant that issued this token.
+ :ivar str signed_start:
+ The datetime this token becomes valid.
+ :ivar str signed_expiry:
+ The datetime this token expires.
+ :ivar str signed_service:
+ What service this key is valid for.
+ :ivar str signed_version:
+ The version identifier of the REST service that created this token.
+ :ivar str value:
+ The user delegation key.
+ """
+ def __init__(self):
+ self.signed_oid = None
+ self.signed_tid = None
+ self.signed_start = None
+ self.signed_expiry = None
+ self.signed_service = None
+ self.signed_version = None
+ self.value = None
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/parser.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/parser.py
new file mode 100644
index 00000000000..c6feba8a639
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/parser.py
@@ -0,0 +1,20 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import sys
+
+if sys.version_info < (3,):
+ def _str(value):
+ if isinstance(value, unicode): # pylint: disable=undefined-variable
+ return value.encode('utf-8')
+
+ return str(value)
+else:
+ _str = str
+
+
+def _to_utc_datetime(value):
+ return value.strftime('%Y-%m-%dT%H:%M:%SZ')
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/policies.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/policies.py
new file mode 100644
index 00000000000..21c689d9cda
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/policies.py
@@ -0,0 +1,657 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+import base64
+import hashlib
+import re
+import random
+from time import time
+from io import SEEK_SET, UnsupportedOperation
+import logging
+import uuid
+from typing import Any, TYPE_CHECKING
+from wsgiref.handlers import format_date_time
+try:
+ from urllib.parse import (
+ urlparse,
+ parse_qsl,
+ urlunparse,
+ urlencode,
+ )
+except ImportError:
+ from urllib import urlencode # type: ignore
+ from urlparse import ( # type: ignore
+ urlparse,
+ parse_qsl,
+ urlunparse,
+ )
+
+from azure.core.pipeline.policies import (
+ BearerTokenCredentialPolicy,
+ HeadersPolicy,
+ HTTPPolicy,
+ NetworkTraceLoggingPolicy,
+ RequestHistory,
+ SansIOHTTPPolicy,
+)
+from azure.core.exceptions import AzureError, ServiceRequestError, ServiceResponseError
+
+from .authentication import StorageHttpChallenge
+from .constants import DEFAULT_OAUTH_SCOPE, STORAGE_OAUTH_SCOPE
+from .models import LocationMode
+
+try:
+ _unicode_type = unicode # type: ignore
+except NameError:
+ _unicode_type = str
+
+if TYPE_CHECKING:
+ from azure.core.credentials import TokenCredential
+ from azure.core.pipeline import PipelineRequest, PipelineResponse
+
+
+_LOGGER = logging.getLogger(__name__)
+
+
+def encode_base64(data):
+ if isinstance(data, _unicode_type):
+ data = data.encode('utf-8')
+ encoded = base64.b64encode(data)
+ return encoded.decode('utf-8')
+
+
+def is_exhausted(settings):
+ """Are we out of retries?"""
+ retry_counts = (settings['total'], settings['connect'], settings['read'], settings['status'])
+ retry_counts = list(filter(None, retry_counts))
+ if not retry_counts:
+ return False
+ return min(retry_counts) < 0
+
+
+def retry_hook(settings, **kwargs):
+ if settings['hook']:
+ settings['hook'](retry_count=settings['count'] - 1, location_mode=settings['mode'], **kwargs)
+
+
+def is_retry(response, mode): # pylint: disable=too-many-return-statements
+ """Is this method/status code retryable? (Based on allowlists and control
+ variables such as the number of total retries to allow, whether to
+ respect the Retry-After header, whether this header is present, and
+ whether the returned status code is on the list of status codes to
+ be retried upon on the presence of the aforementioned header)
+ """
+ status = response.http_response.status_code
+ if 300 <= status < 500:
+ # An exception occured, but in most cases it was expected. Examples could
+ # include a 309 Conflict or 412 Precondition Failed.
+ if status == 404 and mode == LocationMode.SECONDARY:
+ # Response code 404 should be retried if secondary was used.
+ return True
+ if status == 408:
+ # Response code 408 is a timeout and should be retried.
+ return True
+ return False
+ if status >= 500:
+ # Response codes above 500 with the exception of 501 Not Implemented and
+ # 505 Version Not Supported indicate a server issue and should be retried.
+ if status in [501, 505]:
+ return False
+ return True
+ # retry if invalid content md5
+ if response.context.get('validate_content', False) and response.http_response.headers.get('content-md5'):
+ computed_md5 = response.http_request.headers.get('content-md5', None) or \
+ encode_base64(StorageContentValidation.get_content_md5(response.http_response.body()))
+ if response.http_response.headers['content-md5'] != computed_md5:
+ return True
+ return False
+
+
+def urljoin(base_url, stub_url):
+ parsed = urlparse(base_url)
+ parsed = parsed._replace(path=parsed.path + '/' + stub_url)
+ return parsed.geturl()
+
+
+class QueueMessagePolicy(SansIOHTTPPolicy):
+
+ def on_request(self, request):
+ message_id = request.context.options.pop('queue_message_id', None)
+ if message_id:
+ request.http_request.url = urljoin(
+ request.http_request.url,
+ message_id)
+
+
+class StorageHeadersPolicy(HeadersPolicy):
+ request_id_header_name = 'x-ms-client-request-id'
+
+ def on_request(self, request):
+ # type: (PipelineRequest, Any) -> None
+ super(StorageHeadersPolicy, self).on_request(request)
+ current_time = format_date_time(time())
+ request.http_request.headers['x-ms-date'] = current_time
+
+ custom_id = request.context.options.pop('client_request_id', None)
+ request.http_request.headers['x-ms-client-request-id'] = custom_id or str(uuid.uuid1())
+
+ # def on_response(self, request, response):
+ # # raise exception if the echoed client request id from the service is not identical to the one we sent
+ # if self.request_id_header_name in response.http_response.headers:
+
+ # client_request_id = request.http_request.headers.get(self.request_id_header_name)
+
+ # if response.http_response.headers[self.request_id_header_name] != client_request_id:
+ # raise AzureError(
+ # "Echoed client request ID: {} does not match sent client request ID: {}. "
+ # "Service request ID: {}".format(
+ # response.http_response.headers[self.request_id_header_name], client_request_id,
+ # response.http_response.headers['x-ms-request-id']),
+ # response=response.http_response
+ # )
+
+
+class StorageHosts(SansIOHTTPPolicy):
+
+ def __init__(self, hosts=None, **kwargs): # pylint: disable=unused-argument
+ self.hosts = hosts
+ super(StorageHosts, self).__init__()
+
+ def on_request(self, request):
+ # type: (PipelineRequest, Any) -> None
+ request.context.options['hosts'] = self.hosts
+ parsed_url = urlparse(request.http_request.url)
+
+ # Detect what location mode we're currently requesting with
+ location_mode = LocationMode.PRIMARY
+ for key, value in self.hosts.items():
+ if parsed_url.netloc == value:
+ location_mode = key
+
+ # See if a specific location mode has been specified, and if so, redirect
+ use_location = request.context.options.pop('use_location', None)
+ if use_location:
+ # Lock retries to the specific location
+ request.context.options['retry_to_secondary'] = False
+ if use_location not in self.hosts:
+ raise ValueError("Attempting to use undefined host location {}".format(use_location))
+ if use_location != location_mode:
+ # Update request URL to use the specified location
+ updated = parsed_url._replace(netloc=self.hosts[use_location])
+ request.http_request.url = updated.geturl()
+ location_mode = use_location
+
+ request.context.options['location_mode'] = location_mode
+
+
+class StorageLoggingPolicy(NetworkTraceLoggingPolicy):
+ """A policy that logs HTTP request and response to the DEBUG logger.
+
+ This accepts both global configuration, and per-request level with "enable_http_logger"
+ """
+ def __init__(self, logging_enable=False, **kwargs):
+ self.logging_body = kwargs.pop("logging_body", False)
+ super(StorageLoggingPolicy, self).__init__(logging_enable=logging_enable, **kwargs)
+
+ def on_request(self, request):
+ # type: (PipelineRequest, Any) -> None
+ http_request = request.http_request
+ options = request.context.options
+ self.logging_body = self.logging_body or options.pop("logging_body", False)
+ if options.pop("logging_enable", self.enable_http_logger):
+ request.context["logging_enable"] = True
+ if not _LOGGER.isEnabledFor(logging.DEBUG):
+ return
+
+ try:
+ log_url = http_request.url
+ query_params = http_request.query
+ if 'sig' in query_params:
+ log_url = log_url.replace(query_params['sig'], "sig=*****")
+ _LOGGER.debug("Request URL: %r", log_url)
+ _LOGGER.debug("Request method: %r", http_request.method)
+ _LOGGER.debug("Request headers:")
+ for header, value in http_request.headers.items():
+ if header.lower() == 'authorization':
+ value = '*****'
+ elif header.lower() == 'x-ms-copy-source' and 'sig' in value:
+ # take the url apart and scrub away the signed signature
+ scheme, netloc, path, params, query, fragment = urlparse(value)
+ parsed_qs = dict(parse_qsl(query))
+ parsed_qs['sig'] = '*****'
+
+ # the SAS needs to be put back together
+ value = urlunparse((scheme, netloc, path, params, urlencode(parsed_qs), fragment))
+
+ _LOGGER.debug(" %r: %r", header, value)
+ _LOGGER.debug("Request body:")
+
+ if self.logging_body:
+ _LOGGER.debug(str(http_request.body))
+ else:
+ # We don't want to log the binary data of a file upload.
+ _LOGGER.debug("Hidden body, please use logging_body to show body")
+ except Exception as err: # pylint: disable=broad-except
+ _LOGGER.debug("Failed to log request: %r", err)
+
+ def on_response(self, request, response):
+ # type: (PipelineRequest, PipelineResponse, Any) -> None
+ if response.context.pop("logging_enable", self.enable_http_logger):
+ if not _LOGGER.isEnabledFor(logging.DEBUG):
+ return
+
+ try:
+ _LOGGER.debug("Response status: %r", response.http_response.status_code)
+ _LOGGER.debug("Response headers:")
+ for res_header, value in response.http_response.headers.items():
+ _LOGGER.debug(" %r: %r", res_header, value)
+
+ # We don't want to log binary data if the response is a file.
+ _LOGGER.debug("Response content:")
+ pattern = re.compile(r'attachment; ?filename=["\w.]+', re.IGNORECASE)
+ header = response.http_response.headers.get('content-disposition')
+ resp_content_type = response.http_response.headers.get("content-type", "")
+
+ if header and pattern.match(header):
+ filename = header.partition('=')[2]
+ _LOGGER.debug("File attachments: %s", filename)
+ elif resp_content_type.endswith("octet-stream"):
+ _LOGGER.debug("Body contains binary data.")
+ elif resp_content_type.startswith("image"):
+ _LOGGER.debug("Body contains image data.")
+
+ if self.logging_body and resp_content_type.startswith("text"):
+ _LOGGER.debug(response.http_response.text())
+ elif self.logging_body:
+ try:
+ _LOGGER.debug(response.http_response.body())
+ except ValueError:
+ _LOGGER.debug("Body is streamable")
+
+ except Exception as err: # pylint: disable=broad-except
+ _LOGGER.debug("Failed to log response: %s", repr(err))
+
+
+class StorageRequestHook(SansIOHTTPPolicy):
+
+ def __init__(self, **kwargs): # pylint: disable=unused-argument
+ self._request_callback = kwargs.get('raw_request_hook')
+ super(StorageRequestHook, self).__init__()
+
+ def on_request(self, request):
+ # type: (PipelineRequest, **Any) -> PipelineResponse
+ request_callback = request.context.options.pop('raw_request_hook', self._request_callback)
+ if request_callback:
+ request_callback(request)
+
+
+class StorageResponseHook(HTTPPolicy):
+
+ def __init__(self, **kwargs): # pylint: disable=unused-argument
+ self._response_callback = kwargs.get('raw_response_hook')
+ super(StorageResponseHook, self).__init__()
+
+ def send(self, request):
+ # type: (PipelineRequest) -> PipelineResponse
+ # Values could be 0
+ data_stream_total = request.context.get('data_stream_total')
+ if data_stream_total is None:
+ data_stream_total = request.context.options.pop('data_stream_total', None)
+ download_stream_current = request.context.get('download_stream_current')
+ if download_stream_current is None:
+ download_stream_current = request.context.options.pop('download_stream_current', None)
+ upload_stream_current = request.context.get('upload_stream_current')
+ if upload_stream_current is None:
+ upload_stream_current = request.context.options.pop('upload_stream_current', None)
+
+ response_callback = request.context.get('response_callback') or \
+ request.context.options.pop('raw_response_hook', self._response_callback)
+
+ response = self.next.send(request)
+
+ will_retry = is_retry(response, request.context.options.get('mode'))
+ # Auth error could come from Bearer challenge, in which case this request will be made again
+ is_auth_error = response.http_response.status_code == 401
+ should_update_counts = not (will_retry or is_auth_error)
+
+ if should_update_counts and download_stream_current is not None:
+ download_stream_current += int(response.http_response.headers.get('Content-Length', 0))
+ if data_stream_total is None:
+ content_range = response.http_response.headers.get('Content-Range')
+ if content_range:
+ data_stream_total = int(content_range.split(' ', 1)[1].split('/', 1)[1])
+ else:
+ data_stream_total = download_stream_current
+ elif should_update_counts and upload_stream_current is not None:
+ upload_stream_current += int(response.http_request.headers.get('Content-Length', 0))
+ for pipeline_obj in [request, response]:
+ pipeline_obj.context['data_stream_total'] = data_stream_total
+ pipeline_obj.context['download_stream_current'] = download_stream_current
+ pipeline_obj.context['upload_stream_current'] = upload_stream_current
+ if response_callback:
+ response_callback(response)
+ request.context['response_callback'] = response_callback
+ return response
+
+
+class StorageContentValidation(SansIOHTTPPolicy):
+ """A simple policy that sends the given headers
+ with the request.
+
+ This will overwrite any headers already defined in the request.
+ """
+ header_name = 'Content-MD5'
+
+ def __init__(self, **kwargs): # pylint: disable=unused-argument
+ super(StorageContentValidation, self).__init__()
+
+ @staticmethod
+ def get_content_md5(data):
+ md5 = hashlib.md5() # nosec
+ if isinstance(data, bytes):
+ md5.update(data)
+ elif hasattr(data, 'read'):
+ pos = 0
+ try:
+ pos = data.tell()
+ except: # pylint: disable=bare-except
+ pass
+ for chunk in iter(lambda: data.read(4096), b""):
+ md5.update(chunk)
+ try:
+ data.seek(pos, SEEK_SET)
+ except (AttributeError, IOError):
+ raise ValueError("Data should be bytes or a seekable file-like object.")
+ else:
+ raise ValueError("Data should be bytes or a seekable file-like object.")
+
+ return md5.digest()
+
+ def on_request(self, request):
+ # type: (PipelineRequest, Any) -> None
+ validate_content = request.context.options.pop('validate_content', False)
+ if validate_content and request.http_request.method != 'GET':
+ computed_md5 = encode_base64(StorageContentValidation.get_content_md5(request.http_request.data))
+ request.http_request.headers[self.header_name] = computed_md5
+ request.context['validate_content_md5'] = computed_md5
+ request.context['validate_content'] = validate_content
+
+ def on_response(self, request, response):
+ if response.context.get('validate_content', False) and response.http_response.headers.get('content-md5'):
+ computed_md5 = request.context.get('validate_content_md5') or \
+ encode_base64(StorageContentValidation.get_content_md5(response.http_response.body()))
+ if response.http_response.headers['content-md5'] != computed_md5:
+ raise AzureError(
+ 'MD5 mismatch. Expected value is \'{0}\', computed value is \'{1}\'.'.format(
+ response.http_response.headers['content-md5'], computed_md5),
+ response=response.http_response
+ )
+
+
+class StorageRetryPolicy(HTTPPolicy):
+ """
+ The base class for Exponential and Linear retries containing shared code.
+ """
+
+ def __init__(self, **kwargs):
+ self.total_retries = kwargs.pop('retry_total', 10)
+ self.connect_retries = kwargs.pop('retry_connect', 3)
+ self.read_retries = kwargs.pop('retry_read', 3)
+ self.status_retries = kwargs.pop('retry_status', 3)
+ self.retry_to_secondary = kwargs.pop('retry_to_secondary', False)
+ super(StorageRetryPolicy, self).__init__()
+
+ def _set_next_host_location(self, settings, request): # pylint: disable=no-self-use
+ """
+ A function which sets the next host location on the request, if applicable.
+
+ :param ~azure.storage.models.RetryContext context:
+ The retry context containing the previous host location and the request
+ to evaluate and possibly modify.
+ """
+ if settings['hosts'] and all(settings['hosts'].values()):
+ url = urlparse(request.url)
+ # If there's more than one possible location, retry to the alternative
+ if settings['mode'] == LocationMode.PRIMARY:
+ settings['mode'] = LocationMode.SECONDARY
+ else:
+ settings['mode'] = LocationMode.PRIMARY
+ updated = url._replace(netloc=settings['hosts'].get(settings['mode']))
+ request.url = updated.geturl()
+
+ def configure_retries(self, request): # pylint: disable=no-self-use
+ body_position = None
+ if hasattr(request.http_request.body, 'read'):
+ try:
+ body_position = request.http_request.body.tell()
+ except (AttributeError, UnsupportedOperation):
+ # if body position cannot be obtained, then retries will not work
+ pass
+ options = request.context.options
+ return {
+ 'total': options.pop("retry_total", self.total_retries),
+ 'connect': options.pop("retry_connect", self.connect_retries),
+ 'read': options.pop("retry_read", self.read_retries),
+ 'status': options.pop("retry_status", self.status_retries),
+ 'retry_secondary': options.pop("retry_to_secondary", self.retry_to_secondary),
+ 'mode': options.pop("location_mode", LocationMode.PRIMARY),
+ 'hosts': options.pop("hosts", None),
+ 'hook': options.pop("retry_hook", None),
+ 'body_position': body_position,
+ 'count': 0,
+ 'history': []
+ }
+
+ def get_backoff_time(self, settings): # pylint: disable=unused-argument,no-self-use
+ """ Formula for computing the current backoff.
+ Should be calculated by child class.
+
+ :rtype: float
+ """
+ return 0
+
+ def sleep(self, settings, transport):
+ backoff = self.get_backoff_time(settings)
+ if not backoff or backoff < 0:
+ return
+ transport.sleep(backoff)
+
+ def increment(self, settings, request, response=None, error=None):
+ """Increment the retry counters.
+
+ :param response: A pipeline response object.
+ :param error: An error encountered during the request, or
+ None if the response was received successfully.
+
+ :return: Whether the retry attempts are exhausted.
+ """
+ settings['total'] -= 1
+
+ if error and isinstance(error, ServiceRequestError):
+ # Errors when we're fairly sure that the server did not receive the
+ # request, so it should be safe to retry.
+ settings['connect'] -= 1
+ settings['history'].append(RequestHistory(request, error=error))
+
+ elif error and isinstance(error, ServiceResponseError):
+ # Errors that occur after the request has been started, so we should
+ # assume that the server began processing it.
+ settings['read'] -= 1
+ settings['history'].append(RequestHistory(request, error=error))
+
+ else:
+ # Incrementing because of a server error like a 500 in
+ # status_forcelist and a the given method is in the allowlist
+ if response:
+ settings['status'] -= 1
+ settings['history'].append(RequestHistory(request, http_response=response))
+
+ if not is_exhausted(settings):
+ if request.method not in ['PUT'] and settings['retry_secondary']:
+ self._set_next_host_location(settings, request)
+
+ # rewind the request body if it is a stream
+ if request.body and hasattr(request.body, 'read'):
+ # no position was saved, then retry would not work
+ if settings['body_position'] is None:
+ return False
+ try:
+ # attempt to rewind the body to the initial position
+ request.body.seek(settings['body_position'], SEEK_SET)
+ except (UnsupportedOperation, ValueError):
+ # if body is not seekable, then retry would not work
+ return False
+ settings['count'] += 1
+ return True
+ return False
+
+ def send(self, request):
+ retries_remaining = True
+ response = None
+ retry_settings = self.configure_retries(request)
+ while retries_remaining:
+ try:
+ response = self.next.send(request)
+ if is_retry(response, retry_settings['mode']):
+ retries_remaining = self.increment(
+ retry_settings,
+ request=request.http_request,
+ response=response.http_response)
+ if retries_remaining:
+ retry_hook(
+ retry_settings,
+ request=request.http_request,
+ response=response.http_response,
+ error=None)
+ self.sleep(retry_settings, request.context.transport)
+ continue
+ break
+ except AzureError as err:
+ retries_remaining = self.increment(
+ retry_settings, request=request.http_request, error=err)
+ if retries_remaining:
+ retry_hook(
+ retry_settings,
+ request=request.http_request,
+ response=None,
+ error=err)
+ self.sleep(retry_settings, request.context.transport)
+ continue
+ raise err
+ if retry_settings['history']:
+ response.context['history'] = retry_settings['history']
+ response.http_response.location_mode = retry_settings['mode']
+ return response
+
+
+class ExponentialRetry(StorageRetryPolicy):
+ """Exponential retry."""
+
+ def __init__(self, initial_backoff=15, increment_base=3, retry_total=3,
+ retry_to_secondary=False, random_jitter_range=3, **kwargs):
+ '''
+ Constructs an Exponential retry object. The initial_backoff is used for
+ the first retry. Subsequent retries are retried after initial_backoff +
+ increment_power^retry_count seconds.
+
+ :param int initial_backoff:
+ The initial backoff interval, in seconds, for the first retry.
+ :param int increment_base:
+ The base, in seconds, to increment the initial_backoff by after the
+ first retry.
+ :param int max_attempts:
+ The maximum number of retry attempts.
+ :param bool retry_to_secondary:
+ Whether the request should be retried to secondary, if able. This should
+ only be enabled of RA-GRS accounts are used and potentially stale data
+ can be handled.
+ :param int random_jitter_range:
+ A number in seconds which indicates a range to jitter/randomize for the back-off interval.
+ For example, a random_jitter_range of 3 results in the back-off interval x to vary between x+3 and x-3.
+ '''
+ self.initial_backoff = initial_backoff
+ self.increment_base = increment_base
+ self.random_jitter_range = random_jitter_range
+ super(ExponentialRetry, self).__init__(
+ retry_total=retry_total, retry_to_secondary=retry_to_secondary, **kwargs)
+
+ def get_backoff_time(self, settings):
+ """
+ Calculates how long to sleep before retrying.
+
+ :return:
+ An integer indicating how long to wait before retrying the request,
+ or None to indicate no retry should be performed.
+ :rtype: int or None
+ """
+ random_generator = random.Random()
+ backoff = self.initial_backoff + (0 if settings['count'] == 0 else pow(self.increment_base, settings['count']))
+ random_range_start = backoff - self.random_jitter_range if backoff > self.random_jitter_range else 0
+ random_range_end = backoff + self.random_jitter_range
+ return random_generator.uniform(random_range_start, random_range_end)
+
+
+class LinearRetry(StorageRetryPolicy):
+ """Linear retry."""
+
+ def __init__(self, backoff=15, retry_total=3, retry_to_secondary=False, random_jitter_range=3, **kwargs):
+ """
+ Constructs a Linear retry object.
+
+ :param int backoff:
+ The backoff interval, in seconds, between retries.
+ :param int max_attempts:
+ The maximum number of retry attempts.
+ :param bool retry_to_secondary:
+ Whether the request should be retried to secondary, if able. This should
+ only be enabled of RA-GRS accounts are used and potentially stale data
+ can be handled.
+ :param int random_jitter_range:
+ A number in seconds which indicates a range to jitter/randomize for the back-off interval.
+ For example, a random_jitter_range of 3 results in the back-off interval x to vary between x+3 and x-3.
+ """
+ self.backoff = backoff
+ self.random_jitter_range = random_jitter_range
+ super(LinearRetry, self).__init__(
+ retry_total=retry_total, retry_to_secondary=retry_to_secondary, **kwargs)
+
+ def get_backoff_time(self, settings):
+ """
+ Calculates how long to sleep before retrying.
+
+ :return:
+ An integer indicating how long to wait before retrying the request,
+ or None to indicate no retry should be performed.
+ :rtype: int or None
+ """
+ random_generator = random.Random()
+ # the backoff interval normally does not change, however there is the possibility
+ # that it was modified by accessing the property directly after initializing the object
+ random_range_start = self.backoff - self.random_jitter_range \
+ if self.backoff > self.random_jitter_range else 0
+ random_range_end = self.backoff + self.random_jitter_range
+ return random_generator.uniform(random_range_start, random_range_end)
+
+
+class StorageBearerTokenCredentialPolicy(BearerTokenCredentialPolicy):
+ """ Custom Bearer token credential policy for following Storage Bearer challenges """
+
+ def __init__(self, credential, **kwargs):
+ # type: (TokenCredential, **Any) -> None
+ super(StorageBearerTokenCredentialPolicy, self).__init__(credential, STORAGE_OAUTH_SCOPE, **kwargs)
+
+ def on_challenge(self, request, response):
+ # type: (PipelineRequest, PipelineResponse) -> bool
+ try:
+ auth_header = response.http_response.headers.get("WWW-Authenticate")
+ challenge = StorageHttpChallenge(auth_header)
+ except ValueError:
+ return False
+
+ scope = challenge.resource_id + DEFAULT_OAUTH_SCOPE
+ self.authorize_request(request, scope, tenant_id=challenge.tenant_id)
+
+ return True
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/policies_async.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/policies_async.py
new file mode 100644
index 00000000000..b0eae9f1c42
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/policies_async.py
@@ -0,0 +1,253 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=invalid-overridden-method
+
+import asyncio
+import random
+import logging
+from typing import Any, TYPE_CHECKING
+
+from azure.core.pipeline.policies import AsyncBearerTokenCredentialPolicy, AsyncHTTPPolicy
+from azure.core.exceptions import AzureError
+
+from .authentication import StorageHttpChallenge
+from .constants import DEFAULT_OAUTH_SCOPE, STORAGE_OAUTH_SCOPE
+from .policies import is_retry, StorageRetryPolicy
+
+if TYPE_CHECKING:
+ from azure.core.credentials_async import AsyncTokenCredential
+ from azure.core.pipeline import PipelineRequest, PipelineResponse
+
+
+_LOGGER = logging.getLogger(__name__)
+
+
+async def retry_hook(settings, **kwargs):
+ if settings['hook']:
+ if asyncio.iscoroutine(settings['hook']):
+ await settings['hook'](
+ retry_count=settings['count'] - 1,
+ location_mode=settings['mode'],
+ **kwargs)
+ else:
+ settings['hook'](
+ retry_count=settings['count'] - 1,
+ location_mode=settings['mode'],
+ **kwargs)
+
+
+class AsyncStorageResponseHook(AsyncHTTPPolicy):
+
+ def __init__(self, **kwargs): # pylint: disable=unused-argument
+ self._response_callback = kwargs.get('raw_response_hook')
+ super(AsyncStorageResponseHook, self).__init__()
+
+ async def send(self, request):
+ # type: (PipelineRequest) -> PipelineResponse
+ # Values could be 0
+ data_stream_total = request.context.get('data_stream_total')
+ if data_stream_total is None:
+ data_stream_total = request.context.options.pop('data_stream_total', None)
+ download_stream_current = request.context.get('download_stream_current')
+ if download_stream_current is None:
+ download_stream_current = request.context.options.pop('download_stream_current', None)
+ upload_stream_current = request.context.get('upload_stream_current')
+ if upload_stream_current is None:
+ upload_stream_current = request.context.options.pop('upload_stream_current', None)
+
+ response_callback = request.context.get('response_callback') or \
+ request.context.options.pop('raw_response_hook', self._response_callback)
+
+ response = await self.next.send(request)
+ await response.http_response.load_body()
+
+ will_retry = is_retry(response, request.context.options.get('mode'))
+ # Auth error could come from Bearer challenge, in which case this request will be made again
+ is_auth_error = response.http_response.status_code == 401
+ should_update_counts = not (will_retry or is_auth_error)
+
+ if should_update_counts and download_stream_current is not None:
+ download_stream_current += int(response.http_response.headers.get('Content-Length', 0))
+ if data_stream_total is None:
+ content_range = response.http_response.headers.get('Content-Range')
+ if content_range:
+ data_stream_total = int(content_range.split(' ', 1)[1].split('/', 1)[1])
+ else:
+ data_stream_total = download_stream_current
+ elif should_update_counts and upload_stream_current is not None:
+ upload_stream_current += int(response.http_request.headers.get('Content-Length', 0))
+ for pipeline_obj in [request, response]:
+ pipeline_obj.context['data_stream_total'] = data_stream_total
+ pipeline_obj.context['download_stream_current'] = download_stream_current
+ pipeline_obj.context['upload_stream_current'] = upload_stream_current
+ if response_callback:
+ if asyncio.iscoroutine(response_callback):
+ await response_callback(response)
+ else:
+ response_callback(response)
+ request.context['response_callback'] = response_callback
+ return response
+
+class AsyncStorageRetryPolicy(StorageRetryPolicy):
+ """
+ The base class for Exponential and Linear retries containing shared code.
+ """
+
+ async def sleep(self, settings, transport):
+ backoff = self.get_backoff_time(settings)
+ if not backoff or backoff < 0:
+ return
+ await transport.sleep(backoff)
+
+ async def send(self, request):
+ retries_remaining = True
+ response = None
+ retry_settings = self.configure_retries(request)
+ while retries_remaining:
+ try:
+ response = await self.next.send(request)
+ if is_retry(response, retry_settings['mode']):
+ retries_remaining = self.increment(
+ retry_settings,
+ request=request.http_request,
+ response=response.http_response)
+ if retries_remaining:
+ await retry_hook(
+ retry_settings,
+ request=request.http_request,
+ response=response.http_response,
+ error=None)
+ await self.sleep(retry_settings, request.context.transport)
+ continue
+ break
+ except AzureError as err:
+ retries_remaining = self.increment(
+ retry_settings, request=request.http_request, error=err)
+ if retries_remaining:
+ await retry_hook(
+ retry_settings,
+ request=request.http_request,
+ response=None,
+ error=err)
+ await self.sleep(retry_settings, request.context.transport)
+ continue
+ raise err
+ if retry_settings['history']:
+ response.context['history'] = retry_settings['history']
+ response.http_response.location_mode = retry_settings['mode']
+ return response
+
+
+class ExponentialRetry(AsyncStorageRetryPolicy):
+ """Exponential retry."""
+
+ def __init__(self, initial_backoff=15, increment_base=3, retry_total=3,
+ retry_to_secondary=False, random_jitter_range=3, **kwargs):
+ '''
+ Constructs an Exponential retry object. The initial_backoff is used for
+ the first retry. Subsequent retries are retried after initial_backoff +
+ increment_power^retry_count seconds. For example, by default the first retry
+ occurs after 15 seconds, the second after (15+3^1) = 18 seconds, and the
+ third after (15+3^2) = 24 seconds.
+
+ :param int initial_backoff:
+ The initial backoff interval, in seconds, for the first retry.
+ :param int increment_base:
+ The base, in seconds, to increment the initial_backoff by after the
+ first retry.
+ :param int max_attempts:
+ The maximum number of retry attempts.
+ :param bool retry_to_secondary:
+ Whether the request should be retried to secondary, if able. This should
+ only be enabled of RA-GRS accounts are used and potentially stale data
+ can be handled.
+ :param int random_jitter_range:
+ A number in seconds which indicates a range to jitter/randomize for the back-off interval.
+ For example, a random_jitter_range of 3 results in the back-off interval x to vary between x+3 and x-3.
+ '''
+ self.initial_backoff = initial_backoff
+ self.increment_base = increment_base
+ self.random_jitter_range = random_jitter_range
+ super(ExponentialRetry, self).__init__(
+ retry_total=retry_total, retry_to_secondary=retry_to_secondary, **kwargs)
+
+ def get_backoff_time(self, settings):
+ """
+ Calculates how long to sleep before retrying.
+
+ :return:
+ An integer indicating how long to wait before retrying the request,
+ or None to indicate no retry should be performed.
+ :rtype: int or None
+ """
+ random_generator = random.Random()
+ backoff = self.initial_backoff + (0 if settings['count'] == 0 else pow(self.increment_base, settings['count']))
+ random_range_start = backoff - self.random_jitter_range if backoff > self.random_jitter_range else 0
+ random_range_end = backoff + self.random_jitter_range
+ return random_generator.uniform(random_range_start, random_range_end)
+
+
+class LinearRetry(AsyncStorageRetryPolicy):
+ """Linear retry."""
+
+ def __init__(self, backoff=15, retry_total=3, retry_to_secondary=False, random_jitter_range=3, **kwargs):
+ """
+ Constructs a Linear retry object.
+
+ :param int backoff:
+ The backoff interval, in seconds, between retries.
+ :param int max_attempts:
+ The maximum number of retry attempts.
+ :param bool retry_to_secondary:
+ Whether the request should be retried to secondary, if able. This should
+ only be enabled of RA-GRS accounts are used and potentially stale data
+ can be handled.
+ :param int random_jitter_range:
+ A number in seconds which indicates a range to jitter/randomize for the back-off interval.
+ For example, a random_jitter_range of 3 results in the back-off interval x to vary between x+3 and x-3.
+ """
+ self.backoff = backoff
+ self.random_jitter_range = random_jitter_range
+ super(LinearRetry, self).__init__(
+ retry_total=retry_total, retry_to_secondary=retry_to_secondary, **kwargs)
+
+ def get_backoff_time(self, settings):
+ """
+ Calculates how long to sleep before retrying.
+
+ :return:
+ An integer indicating how long to wait before retrying the request,
+ or None to indicate no retry should be performed.
+ :rtype: int or None
+ """
+ random_generator = random.Random()
+ # the backoff interval normally does not change, however there is the possibility
+ # that it was modified by accessing the property directly after initializing the object
+ random_range_start = self.backoff - self.random_jitter_range \
+ if self.backoff > self.random_jitter_range else 0
+ random_range_end = self.backoff + self.random_jitter_range
+ return random_generator.uniform(random_range_start, random_range_end)
+
+
+class AsyncStorageBearerTokenCredentialPolicy(AsyncBearerTokenCredentialPolicy):
+ """ Custom Bearer token credential policy for following Storage Bearer challenges """
+
+ def __init__(self, credential, **kwargs):
+ # type: (AsyncTokenCredential, **Any) -> None
+ super(AsyncStorageBearerTokenCredentialPolicy, self).__init__(credential, STORAGE_OAUTH_SCOPE, **kwargs)
+
+ async def on_challenge(self, request, response):
+ # type: (PipelineRequest, PipelineResponse) -> bool
+ try:
+ auth_header = response.http_response.headers.get("WWW-Authenticate")
+ challenge = StorageHttpChallenge(auth_header)
+ except ValueError:
+ return False
+
+ scope = challenge.resource_id + DEFAULT_OAUTH_SCOPE
+ await self.authorize_request(request, scope, tenant_id=challenge.tenant_id)
+
+ return True
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/request_handlers.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/request_handlers.py
new file mode 100644
index 00000000000..ba760434cac
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/request_handlers.py
@@ -0,0 +1,278 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+from typing import ( # pylint: disable=unused-import
+ Union, Optional, Any, Iterable, Dict, List, Type, Tuple,
+ TYPE_CHECKING
+)
+
+import logging
+from os import fstat
+import stat
+from io import (SEEK_END, SEEK_SET, UnsupportedOperation)
+
+import isodate
+
+from azure.core.exceptions import raise_with_traceback
+
+
+_LOGGER = logging.getLogger(__name__)
+
+_REQUEST_DELIMITER_PREFIX = "batch_"
+_HTTP1_1_IDENTIFIER = "HTTP/1.1"
+_HTTP_LINE_ENDING = "\r\n"
+
+
+def serialize_iso(attr):
+ """Serialize Datetime object into ISO-8601 formatted string.
+
+ :param Datetime attr: Object to be serialized.
+ :rtype: str
+ :raises: ValueError if format invalid.
+ """
+ if not attr:
+ return None
+ if isinstance(attr, str):
+ attr = isodate.parse_datetime(attr)
+ try:
+ utc = attr.utctimetuple()
+ if utc.tm_year > 9999 or utc.tm_year < 1:
+ raise OverflowError("Hit max or min date")
+
+ date = "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}".format(
+ utc.tm_year, utc.tm_mon, utc.tm_mday,
+ utc.tm_hour, utc.tm_min, utc.tm_sec)
+ return date + 'Z'
+ except (ValueError, OverflowError) as err:
+ msg = "Unable to serialize datetime object."
+ raise_with_traceback(ValueError, msg, err)
+ except AttributeError as err:
+ msg = "ISO-8601 object must be valid Datetime object."
+ raise_with_traceback(TypeError, msg, err)
+
+
+def get_length(data):
+ length = None
+ # Check if object implements the __len__ method, covers most input cases such as bytearray.
+ try:
+ length = len(data)
+ except: # pylint: disable=bare-except
+ pass
+
+ if not length:
+ # Check if the stream is a file-like stream object.
+ # If so, calculate the size using the file descriptor.
+ try:
+ fileno = data.fileno()
+ except (AttributeError, UnsupportedOperation):
+ pass
+ else:
+ try:
+ mode = fstat(fileno).st_mode
+ if stat.S_ISREG(mode) or stat.S_ISLNK(mode):
+ #st_size only meaningful if regular file or symlink, other types
+ # e.g. sockets may return misleading sizes like 0
+ return fstat(fileno).st_size
+ except OSError:
+ # Not a valid fileno, may be possible requests returned
+ # a socket number?
+ pass
+
+ # If the stream is seekable and tell() is implemented, calculate the stream size.
+ try:
+ current_position = data.tell()
+ data.seek(0, SEEK_END)
+ length = data.tell() - current_position
+ data.seek(current_position, SEEK_SET)
+ except (AttributeError, OSError, UnsupportedOperation):
+ pass
+
+ return length
+
+
+def read_length(data):
+ try:
+ if hasattr(data, 'read'):
+ read_data = b''
+ for chunk in iter(lambda: data.read(4096), b""):
+ read_data += chunk
+ return len(read_data), read_data
+ if hasattr(data, '__iter__'):
+ read_data = b''
+ for chunk in data:
+ read_data += chunk
+ return len(read_data), read_data
+ except: # pylint: disable=bare-except
+ pass
+ raise ValueError("Unable to calculate content length, please specify.")
+
+
+def validate_and_format_range_headers(
+ start_range, end_range, start_range_required=True,
+ end_range_required=True, check_content_md5=False, align_to_page=False):
+ # If end range is provided, start range must be provided
+ if (start_range_required or end_range is not None) and start_range is None:
+ raise ValueError("start_range value cannot be None.")
+ if end_range_required and end_range is None:
+ raise ValueError("end_range value cannot be None.")
+
+ # Page ranges must be 512 aligned
+ if align_to_page:
+ if start_range is not None and start_range % 512 != 0:
+ raise ValueError("Invalid page blob start_range: {0}. "
+ "The size must be aligned to a 512-byte boundary.".format(start_range))
+ if end_range is not None and end_range % 512 != 511:
+ raise ValueError("Invalid page blob end_range: {0}. "
+ "The size must be aligned to a 512-byte boundary.".format(end_range))
+
+ # Format based on whether end_range is present
+ range_header = None
+ if end_range is not None:
+ range_header = 'bytes={0}-{1}'.format(start_range, end_range)
+ elif start_range is not None:
+ range_header = "bytes={0}-".format(start_range)
+
+ # Content MD5 can only be provided for a complete range less than 4MB in size
+ range_validation = None
+ if check_content_md5:
+ if start_range is None or end_range is None:
+ raise ValueError("Both start and end range requied for MD5 content validation.")
+ if end_range - start_range > 4 * 1024 * 1024:
+ raise ValueError("Getting content MD5 for a range greater than 4MB is not supported.")
+ range_validation = 'true'
+
+ return range_header, range_validation
+
+
+def add_metadata_headers(metadata=None):
+ # type: (Optional[Dict[str, str]]) -> Dict[str, str]
+ headers = {}
+ if metadata:
+ for key, value in metadata.items():
+ headers['x-ms-meta-{}'.format(key.strip())] = value.strip() if value else value
+ return headers
+
+
+def serialize_batch_body(requests, batch_id):
+ """
+ --
+
+ --
+ (repeated as needed)
+ ----
+
+ Serializes the requests in this batch to a single HTTP mixed/multipart body.
+
+ :param list[~azure.core.pipeline.transport.HttpRequest] requests:
+ a list of sub-request for the batch request
+ :param str batch_id:
+ to be embedded in batch sub-request delimiter
+ :return: The body bytes for this batch.
+ """
+
+ if requests is None or len(requests) == 0:
+ raise ValueError('Please provide sub-request(s) for this batch request')
+
+ delimiter_bytes = (_get_batch_request_delimiter(batch_id, True, False) + _HTTP_LINE_ENDING).encode('utf-8')
+ newline_bytes = _HTTP_LINE_ENDING.encode('utf-8')
+ batch_body = list()
+
+ content_index = 0
+ for request in requests:
+ request.headers.update({
+ "Content-ID": str(content_index),
+ "Content-Length": str(0)
+ })
+ batch_body.append(delimiter_bytes)
+ batch_body.append(_make_body_from_sub_request(request))
+ batch_body.append(newline_bytes)
+ content_index += 1
+
+ batch_body.append(_get_batch_request_delimiter(batch_id, True, True).encode('utf-8'))
+ # final line of body MUST have \r\n at the end, or it will not be properly read by the service
+ batch_body.append(newline_bytes)
+
+ return bytes().join(batch_body)
+
+
+def _get_batch_request_delimiter(batch_id, is_prepend_dashes=False, is_append_dashes=False):
+ """
+ Gets the delimiter used for this batch request's mixed/multipart HTTP format.
+
+ :param str batch_id:
+ Randomly generated id
+ :param bool is_prepend_dashes:
+ Whether to include the starting dashes. Used in the body, but non on defining the delimiter.
+ :param bool is_append_dashes:
+ Whether to include the ending dashes. Used in the body on the closing delimiter only.
+ :return: The delimiter, WITHOUT a trailing newline.
+ """
+
+ prepend_dashes = '--' if is_prepend_dashes else ''
+ append_dashes = '--' if is_append_dashes else ''
+
+ return prepend_dashes + _REQUEST_DELIMITER_PREFIX + batch_id + append_dashes
+
+
+def _make_body_from_sub_request(sub_request):
+ """
+ Content-Type: application/http
+ Content-ID:
+ Content-Transfer-Encoding: (if present)
+
+ HTTP/
+ : (repeated as necessary)
+ Content-Length:
+ (newline if content length > 0)
+ (if content length > 0)
+
+ Serializes an http request.
+
+ :param ~azure.core.pipeline.transport.HttpRequest sub_request:
+ Request to serialize.
+ :return: The serialized sub-request in bytes
+ """
+
+ # put the sub-request's headers into a list for efficient str concatenation
+ sub_request_body = list()
+
+ # get headers for ease of manipulation; remove headers as they are used
+ headers = sub_request.headers
+
+ # append opening headers
+ sub_request_body.append("Content-Type: application/http")
+ sub_request_body.append(_HTTP_LINE_ENDING)
+
+ sub_request_body.append("Content-ID: ")
+ sub_request_body.append(headers.pop("Content-ID", ""))
+ sub_request_body.append(_HTTP_LINE_ENDING)
+
+ sub_request_body.append("Content-Transfer-Encoding: binary")
+ sub_request_body.append(_HTTP_LINE_ENDING)
+
+ # append blank line
+ sub_request_body.append(_HTTP_LINE_ENDING)
+
+ # append HTTP verb and path and query and HTTP version
+ sub_request_body.append(sub_request.method)
+ sub_request_body.append(' ')
+ sub_request_body.append(sub_request.url)
+ sub_request_body.append(' ')
+ sub_request_body.append(_HTTP1_1_IDENTIFIER)
+ sub_request_body.append(_HTTP_LINE_ENDING)
+
+ # append remaining headers (this will set the Content-Length, as it was set on `sub-request`)
+ for header_name, header_value in headers.items():
+ if header_value is not None:
+ sub_request_body.append(header_name)
+ sub_request_body.append(": ")
+ sub_request_body.append(header_value)
+ sub_request_body.append(_HTTP_LINE_ENDING)
+
+ # append blank line
+ sub_request_body.append(_HTTP_LINE_ENDING)
+
+ return ''.join(sub_request_body).encode()
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/response_handlers.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/response_handlers.py
new file mode 100644
index 00000000000..4d90a17f4db
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/response_handlers.py
@@ -0,0 +1,195 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+from typing import ( # pylint: disable=unused-import
+ Union, Optional, Any, Iterable, Dict, List, Type, Tuple,
+ TYPE_CHECKING
+)
+import logging
+from xml.etree.ElementTree import Element
+
+from azure.core.pipeline.policies import ContentDecodePolicy
+from azure.core.exceptions import (
+ HttpResponseError,
+ ResourceNotFoundError,
+ ResourceModifiedError,
+ ResourceExistsError,
+ ClientAuthenticationError,
+ DecodeError)
+
+from .parser import _to_utc_datetime
+from .models import StorageErrorCode, UserDelegationKey, get_enum_value
+
+if TYPE_CHECKING:
+ from datetime import datetime
+ from azure.core.exceptions import AzureError
+
+
+_LOGGER = logging.getLogger(__name__)
+
+
+class PartialBatchErrorException(HttpResponseError):
+ """There is a partial failure in batch operations.
+
+ :param str message: The message of the exception.
+ :param response: Server response to be deserialized.
+ :param list parts: A list of the parts in multipart response.
+ """
+
+ def __init__(self, message, response, parts):
+ self.parts = parts
+ super(PartialBatchErrorException, self).__init__(message=message, response=response)
+
+
+def parse_length_from_content_range(content_range):
+ '''
+ Parses the blob length from the content range header: bytes 1-3/65537
+ '''
+ if content_range is None:
+ return None
+
+ # First, split in space and take the second half: '1-3/65537'
+ # Next, split on slash and take the second half: '65537'
+ # Finally, convert to an int: 65537
+ return int(content_range.split(' ', 1)[1].split('/', 1)[1])
+
+
+def normalize_headers(headers):
+ normalized = {}
+ for key, value in headers.items():
+ if key.startswith('x-ms-'):
+ key = key[5:]
+ normalized[key.lower().replace('-', '_')] = get_enum_value(value)
+ return normalized
+
+
+def deserialize_metadata(response, obj, headers): # pylint: disable=unused-argument
+ raw_metadata = {k: v for k, v in response.http_response.headers.items() if k.startswith("x-ms-meta-")}
+ return {k[10:]: v for k, v in raw_metadata.items()}
+
+
+def return_response_headers(response, deserialized, response_headers): # pylint: disable=unused-argument
+ return normalize_headers(response_headers)
+
+
+def return_headers_and_deserialized(response, deserialized, response_headers): # pylint: disable=unused-argument
+ return normalize_headers(response_headers), deserialized
+
+
+def return_context_and_deserialized(response, deserialized, response_headers): # pylint: disable=unused-argument
+ return response.http_response.location_mode, deserialized
+
+
+def process_storage_error(storage_error): # pylint:disable=too-many-statements
+ raise_error = HttpResponseError
+ serialized = False
+ if not storage_error.response:
+ raise storage_error
+ # If it is one of those three then it has been serialized prior by the generated layer.
+ if isinstance(storage_error, (PartialBatchErrorException,
+ ClientAuthenticationError, ResourceNotFoundError, ResourceExistsError)):
+ serialized = True
+ error_code = storage_error.response.headers.get('x-ms-error-code')
+ error_message = storage_error.message
+ additional_data = {}
+ error_dict = {}
+ try:
+ error_body = ContentDecodePolicy.deserialize_from_http_generics(storage_error.response)
+ try:
+ error_body = error_body or storage_error.response.reason
+ except AttributeError:
+ error_body = ''
+ # If it is an XML response
+ if isinstance(error_body, Element):
+ error_dict = {
+ child.tag.lower(): child.text
+ for child in error_body
+ }
+ # If it is a JSON response
+ elif isinstance(error_body, dict):
+ error_dict = error_body.get('error', {})
+ elif not error_code:
+ _LOGGER.warning(
+ 'Unexpected return type %s from ContentDecodePolicy.deserialize_from_http_generics.', type(error_body))
+ error_dict = {'message': str(error_body)}
+
+ # If we extracted from a Json or XML response
+ if error_dict:
+ error_code = error_dict.get('code')
+ error_message = error_dict.get('message')
+ additional_data = {k: v for k, v in error_dict.items() if k not in {'code', 'message'}}
+ except DecodeError:
+ pass
+
+ try:
+ # This check would be unnecessary if we have already serialized the error
+ if error_code and not serialized:
+ error_code = StorageErrorCode(error_code)
+ if error_code in [StorageErrorCode.condition_not_met,
+ StorageErrorCode.blob_overwritten]:
+ raise_error = ResourceModifiedError
+ if error_code in [StorageErrorCode.invalid_authentication_info,
+ StorageErrorCode.authentication_failed]:
+ raise_error = ClientAuthenticationError
+ if error_code in [StorageErrorCode.resource_not_found,
+ StorageErrorCode.cannot_verify_copy_source,
+ StorageErrorCode.blob_not_found,
+ StorageErrorCode.queue_not_found,
+ StorageErrorCode.container_not_found,
+ StorageErrorCode.parent_not_found,
+ StorageErrorCode.share_not_found]:
+ raise_error = ResourceNotFoundError
+ if error_code in [StorageErrorCode.account_already_exists,
+ StorageErrorCode.account_being_created,
+ StorageErrorCode.resource_already_exists,
+ StorageErrorCode.resource_type_mismatch,
+ StorageErrorCode.blob_already_exists,
+ StorageErrorCode.queue_already_exists,
+ StorageErrorCode.container_already_exists,
+ StorageErrorCode.container_being_deleted,
+ StorageErrorCode.queue_being_deleted,
+ StorageErrorCode.share_already_exists,
+ StorageErrorCode.share_being_deleted]:
+ raise_error = ResourceExistsError
+ except ValueError:
+ # Got an unknown error code
+ pass
+
+ # Error message should include all the error properties
+ try:
+ error_message += "\nErrorCode:{}".format(error_code.value)
+ except AttributeError:
+ error_message += "\nErrorCode:{}".format(error_code)
+ for name, info in additional_data.items():
+ error_message += "\n{}:{}".format(name, info)
+
+ # No need to create an instance if it has already been serialized by the generated layer
+ if serialized:
+ storage_error.message = error_message
+ error = storage_error
+ else:
+ error = raise_error(message=error_message, response=storage_error.response)
+ # Ensure these properties are stored in the error instance as well (not just the error message)
+ error.error_code = error_code
+ error.additional_info = additional_data
+ # error.args is what's surfaced on the traceback - show error message in all cases
+ error.args = (error.message,)
+ try:
+ # `from None` prevents us from double printing the exception (suppresses generated layer error context)
+ exec("raise error from None") # pylint: disable=exec-used # nosec
+ except SyntaxError:
+ raise error
+
+
+def parse_to_internal_user_delegation_key(service_user_delegation_key):
+ internal_user_delegation_key = UserDelegationKey()
+ internal_user_delegation_key.signed_oid = service_user_delegation_key.signed_oid
+ internal_user_delegation_key.signed_tid = service_user_delegation_key.signed_tid
+ internal_user_delegation_key.signed_start = _to_utc_datetime(service_user_delegation_key.signed_start)
+ internal_user_delegation_key.signed_expiry = _to_utc_datetime(service_user_delegation_key.signed_expiry)
+ internal_user_delegation_key.signed_service = service_user_delegation_key.signed_service
+ internal_user_delegation_key.signed_version = service_user_delegation_key.signed_version
+ internal_user_delegation_key.value = service_user_delegation_key.value
+ return internal_user_delegation_key
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/shared_access_signature.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/shared_access_signature.py
new file mode 100644
index 00000000000..d2ebfc4b809
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/shared_access_signature.py
@@ -0,0 +1,230 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+from datetime import date
+
+from .parser import _str, _to_utc_datetime
+from .constants import X_MS_VERSION
+from . import sign_string, url_quote
+
+
+class QueryStringConstants(object):
+ SIGNED_SIGNATURE = 'sig'
+ SIGNED_PERMISSION = 'sp'
+ SIGNED_START = 'st'
+ SIGNED_EXPIRY = 'se'
+ SIGNED_RESOURCE = 'sr'
+ SIGNED_IDENTIFIER = 'si'
+ SIGNED_IP = 'sip'
+ SIGNED_PROTOCOL = 'spr'
+ SIGNED_VERSION = 'sv'
+ SIGNED_CACHE_CONTROL = 'rscc'
+ SIGNED_CONTENT_DISPOSITION = 'rscd'
+ SIGNED_CONTENT_ENCODING = 'rsce'
+ SIGNED_CONTENT_LANGUAGE = 'rscl'
+ SIGNED_CONTENT_TYPE = 'rsct'
+ START_PK = 'spk'
+ START_RK = 'srk'
+ END_PK = 'epk'
+ END_RK = 'erk'
+ SIGNED_RESOURCE_TYPES = 'srt'
+ SIGNED_SERVICES = 'ss'
+ SIGNED_OID = 'skoid'
+ SIGNED_TID = 'sktid'
+ SIGNED_KEY_START = 'skt'
+ SIGNED_KEY_EXPIRY = 'ske'
+ SIGNED_KEY_SERVICE = 'sks'
+ SIGNED_KEY_VERSION = 'skv'
+
+ # for blob only
+ SIGNED_ENCRYPTION_SCOPE = 'ses'
+
+ # for ADLS
+ SIGNED_AUTHORIZED_OID = 'saoid'
+ SIGNED_UNAUTHORIZED_OID = 'suoid'
+ SIGNED_CORRELATION_ID = 'scid'
+ SIGNED_DIRECTORY_DEPTH = 'sdd'
+
+ @staticmethod
+ def to_list():
+ return [
+ QueryStringConstants.SIGNED_SIGNATURE,
+ QueryStringConstants.SIGNED_PERMISSION,
+ QueryStringConstants.SIGNED_START,
+ QueryStringConstants.SIGNED_EXPIRY,
+ QueryStringConstants.SIGNED_RESOURCE,
+ QueryStringConstants.SIGNED_IDENTIFIER,
+ QueryStringConstants.SIGNED_IP,
+ QueryStringConstants.SIGNED_PROTOCOL,
+ QueryStringConstants.SIGNED_VERSION,
+ QueryStringConstants.SIGNED_CACHE_CONTROL,
+ QueryStringConstants.SIGNED_CONTENT_DISPOSITION,
+ QueryStringConstants.SIGNED_CONTENT_ENCODING,
+ QueryStringConstants.SIGNED_CONTENT_LANGUAGE,
+ QueryStringConstants.SIGNED_CONTENT_TYPE,
+ QueryStringConstants.START_PK,
+ QueryStringConstants.START_RK,
+ QueryStringConstants.END_PK,
+ QueryStringConstants.END_RK,
+ QueryStringConstants.SIGNED_RESOURCE_TYPES,
+ QueryStringConstants.SIGNED_SERVICES,
+ QueryStringConstants.SIGNED_OID,
+ QueryStringConstants.SIGNED_TID,
+ QueryStringConstants.SIGNED_KEY_START,
+ QueryStringConstants.SIGNED_KEY_EXPIRY,
+ QueryStringConstants.SIGNED_KEY_SERVICE,
+ QueryStringConstants.SIGNED_KEY_VERSION,
+ # for blob only
+ QueryStringConstants.SIGNED_ENCRYPTION_SCOPE,
+ # for ADLS
+ QueryStringConstants.SIGNED_AUTHORIZED_OID,
+ QueryStringConstants.SIGNED_UNAUTHORIZED_OID,
+ QueryStringConstants.SIGNED_CORRELATION_ID,
+ QueryStringConstants.SIGNED_DIRECTORY_DEPTH,
+ ]
+
+
+class SharedAccessSignature(object):
+ '''
+ Provides a factory for creating account access
+ signature tokens with an account name and account key. Users can either
+ use the factory or can construct the appropriate service and use the
+ generate_*_shared_access_signature method directly.
+ '''
+
+ def __init__(self, account_name, account_key, x_ms_version=X_MS_VERSION):
+ '''
+ :param str account_name:
+ The storage account name used to generate the shared access signatures.
+ :param str account_key:
+ The access key to generate the shares access signatures.
+ :param str x_ms_version:
+ The service version used to generate the shared access signatures.
+ '''
+ self.account_name = account_name
+ self.account_key = account_key
+ self.x_ms_version = x_ms_version
+
+ def generate_account(self, services, resource_types, permission, expiry, start=None,
+ ip=None, protocol=None, **kwargs):
+ '''
+ Generates a shared access signature for the account.
+ Use the returned signature with the sas_token parameter of the service
+ or to create a new account object.
+
+ :param ResourceTypes resource_types:
+ Specifies the resource types that are accessible with the account
+ SAS. You can combine values to provide access to more than one
+ resource type.
+ :param AccountSasPermissions permission:
+ The permissions associated with the shared access signature. The
+ user is restricted to operations allowed by the permissions.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has been
+ specified in an associated stored access policy. You can combine
+ values to provide more than one permission.
+ :param expiry:
+ The time at which the shared access signature becomes invalid.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has
+ been specified in an associated stored access policy. Azure will always
+ convert values to UTC. If a date is passed in without timezone info, it
+ is assumed to be UTC.
+ :type expiry: datetime or str
+ :param start:
+ The time at which the shared access signature becomes valid. If
+ omitted, start time for this call is assumed to be the time when the
+ storage service receives the request. Azure will always convert values
+ to UTC. If a date is passed in without timezone info, it is assumed to
+ be UTC.
+ :type start: datetime or str
+ :param str ip:
+ Specifies an IP address or a range of IP addresses from which to accept requests.
+ If the IP address from which the request originates does not match the IP address
+ or address range specified on the SAS token, the request is not authenticated.
+ For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS
+ restricts the request to those IP addresses.
+ :param str protocol:
+ Specifies the protocol permitted for a request made. The default value
+ is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values.
+ '''
+ sas = _SharedAccessHelper()
+ sas.add_base(permission, expiry, start, ip, protocol, self.x_ms_version)
+ sas.add_account(services, resource_types)
+ sas.add_encryption_scope(**kwargs)
+ sas.add_account_signature(self.account_name, self.account_key)
+
+ return sas.get_token()
+
+
+class _SharedAccessHelper(object):
+ def __init__(self):
+ self.query_dict = {}
+
+ def _add_query(self, name, val):
+ if val:
+ self.query_dict[name] = _str(val) if val is not None else None
+
+ def add_encryption_scope(self, **kwargs):
+ self._add_query(QueryStringConstants.SIGNED_ENCRYPTION_SCOPE, kwargs.pop('encryption_scope', None))
+
+ def add_base(self, permission, expiry, start, ip, protocol, x_ms_version):
+ if isinstance(start, date):
+ start = _to_utc_datetime(start)
+
+ if isinstance(expiry, date):
+ expiry = _to_utc_datetime(expiry)
+
+ self._add_query(QueryStringConstants.SIGNED_START, start)
+ self._add_query(QueryStringConstants.SIGNED_EXPIRY, expiry)
+ self._add_query(QueryStringConstants.SIGNED_PERMISSION, permission)
+ self._add_query(QueryStringConstants.SIGNED_IP, ip)
+ self._add_query(QueryStringConstants.SIGNED_PROTOCOL, protocol)
+ self._add_query(QueryStringConstants.SIGNED_VERSION, x_ms_version)
+
+ def add_resource(self, resource):
+ self._add_query(QueryStringConstants.SIGNED_RESOURCE, resource)
+
+ def add_id(self, policy_id):
+ self._add_query(QueryStringConstants.SIGNED_IDENTIFIER, policy_id)
+
+ def add_account(self, services, resource_types):
+ self._add_query(QueryStringConstants.SIGNED_SERVICES, services)
+ self._add_query(QueryStringConstants.SIGNED_RESOURCE_TYPES, resource_types)
+
+ def add_override_response_headers(self, cache_control,
+ content_disposition,
+ content_encoding,
+ content_language,
+ content_type):
+ self._add_query(QueryStringConstants.SIGNED_CACHE_CONTROL, cache_control)
+ self._add_query(QueryStringConstants.SIGNED_CONTENT_DISPOSITION, content_disposition)
+ self._add_query(QueryStringConstants.SIGNED_CONTENT_ENCODING, content_encoding)
+ self._add_query(QueryStringConstants.SIGNED_CONTENT_LANGUAGE, content_language)
+ self._add_query(QueryStringConstants.SIGNED_CONTENT_TYPE, content_type)
+
+ def add_account_signature(self, account_name, account_key):
+ def get_value_to_append(query):
+ return_value = self.query_dict.get(query) or ''
+ return return_value + '\n'
+
+ string_to_sign = \
+ (account_name + '\n' +
+ get_value_to_append(QueryStringConstants.SIGNED_PERMISSION) +
+ get_value_to_append(QueryStringConstants.SIGNED_SERVICES) +
+ get_value_to_append(QueryStringConstants.SIGNED_RESOURCE_TYPES) +
+ get_value_to_append(QueryStringConstants.SIGNED_START) +
+ get_value_to_append(QueryStringConstants.SIGNED_EXPIRY) +
+ get_value_to_append(QueryStringConstants.SIGNED_IP) +
+ get_value_to_append(QueryStringConstants.SIGNED_PROTOCOL) +
+ get_value_to_append(QueryStringConstants.SIGNED_VERSION) +
+ get_value_to_append(QueryStringConstants.SIGNED_ENCRYPTION_SCOPE))
+
+ self._add_query(QueryStringConstants.SIGNED_SIGNATURE,
+ sign_string(account_key, string_to_sign))
+
+ def get_token(self):
+ return '&'.join(['{0}={1}'.format(n, url_quote(v)) for n, v in self.query_dict.items() if v is not None])
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/uploads.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/uploads.py
new file mode 100644
index 00000000000..941a90faf53
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/uploads.py
@@ -0,0 +1,603 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=no-self-use
+
+from concurrent import futures
+from io import (BytesIO, IOBase, SEEK_CUR, SEEK_END, SEEK_SET, UnsupportedOperation)
+from threading import Lock
+from itertools import islice
+from math import ceil
+
+import six
+
+from azure.core.tracing.common import with_current_context
+
+from . import encode_base64, url_quote
+from .request_handlers import get_length
+from .response_handlers import return_response_headers
+from .encryption import get_blob_encryptor_and_padder
+
+
+_LARGE_BLOB_UPLOAD_MAX_READ_BUFFER_SIZE = 4 * 1024 * 1024
+_ERROR_VALUE_SHOULD_BE_SEEKABLE_STREAM = "{0} should be a seekable file-like/io.IOBase type stream object."
+
+
+def _parallel_uploads(executor, uploader, pending, running):
+ range_ids = []
+ while True:
+ # Wait for some download to finish before adding a new one
+ done, running = futures.wait(running, return_when=futures.FIRST_COMPLETED)
+ range_ids.extend([chunk.result() for chunk in done])
+ try:
+ for _ in range(0, len(done)):
+ next_chunk = next(pending)
+ running.add(executor.submit(with_current_context(uploader), next_chunk))
+ except StopIteration:
+ break
+
+ # Wait for the remaining uploads to finish
+ done, _running = futures.wait(running)
+ range_ids.extend([chunk.result() for chunk in done])
+ return range_ids
+
+
+def upload_data_chunks(
+ service=None,
+ uploader_class=None,
+ total_size=None,
+ chunk_size=None,
+ max_concurrency=None,
+ stream=None,
+ validate_content=None,
+ encryption_options=None,
+ **kwargs):
+
+ if encryption_options:
+ encryptor, padder = get_blob_encryptor_and_padder(
+ encryption_options.get('cek'),
+ encryption_options.get('vector'),
+ uploader_class is not PageBlobChunkUploader)
+ kwargs['encryptor'] = encryptor
+ kwargs['padder'] = padder
+
+ parallel = max_concurrency > 1
+ if parallel and 'modified_access_conditions' in kwargs:
+ # Access conditions do not work with parallelism
+ kwargs['modified_access_conditions'] = None
+
+ uploader = uploader_class(
+ service=service,
+ total_size=total_size,
+ chunk_size=chunk_size,
+ stream=stream,
+ parallel=parallel,
+ validate_content=validate_content,
+ **kwargs)
+ if parallel:
+ with futures.ThreadPoolExecutor(max_concurrency) as executor:
+ upload_tasks = uploader.get_chunk_streams()
+ running_futures = [
+ executor.submit(with_current_context(uploader.process_chunk), u)
+ for u in islice(upload_tasks, 0, max_concurrency)
+ ]
+ range_ids = _parallel_uploads(executor, uploader.process_chunk, upload_tasks, running_futures)
+ else:
+ range_ids = [uploader.process_chunk(result) for result in uploader.get_chunk_streams()]
+ if any(range_ids):
+ return [r[1] for r in sorted(range_ids, key=lambda r: r[0])]
+ return uploader.response_headers
+
+
+def upload_substream_blocks(
+ service=None,
+ uploader_class=None,
+ total_size=None,
+ chunk_size=None,
+ max_concurrency=None,
+ stream=None,
+ **kwargs):
+ parallel = max_concurrency > 1
+ if parallel and 'modified_access_conditions' in kwargs:
+ # Access conditions do not work with parallelism
+ kwargs['modified_access_conditions'] = None
+ uploader = uploader_class(
+ service=service,
+ total_size=total_size,
+ chunk_size=chunk_size,
+ stream=stream,
+ parallel=parallel,
+ **kwargs)
+
+ if parallel:
+ with futures.ThreadPoolExecutor(max_concurrency) as executor:
+ upload_tasks = uploader.get_substream_blocks()
+ running_futures = [
+ executor.submit(with_current_context(uploader.process_substream_block), u)
+ for u in islice(upload_tasks, 0, max_concurrency)
+ ]
+ range_ids = _parallel_uploads(executor, uploader.process_substream_block, upload_tasks, running_futures)
+ else:
+ range_ids = [uploader.process_substream_block(b) for b in uploader.get_substream_blocks()]
+ if any(range_ids):
+ return sorted(range_ids)
+ return []
+
+
+class _ChunkUploader(object): # pylint: disable=too-many-instance-attributes
+
+ def __init__(self, service, total_size, chunk_size, stream, parallel, encryptor=None, padder=None, **kwargs):
+ self.service = service
+ self.total_size = total_size
+ self.chunk_size = chunk_size
+ self.stream = stream
+ self.parallel = parallel
+
+ # Stream management
+ self.stream_start = stream.tell() if parallel else None
+ self.stream_lock = Lock() if parallel else None
+
+ # Progress feedback
+ self.progress_total = 0
+ self.progress_lock = Lock() if parallel else None
+
+ # Encryption
+ self.encryptor = encryptor
+ self.padder = padder
+ self.response_headers = None
+ self.etag = None
+ self.last_modified = None
+ self.request_options = kwargs
+
+ def get_chunk_streams(self):
+ index = 0
+ while True:
+ data = b""
+ read_size = self.chunk_size
+
+ # Buffer until we either reach the end of the stream or get a whole chunk.
+ while True:
+ if self.total_size:
+ read_size = min(self.chunk_size - len(data), self.total_size - (index + len(data)))
+ temp = self.stream.read(read_size)
+ if not isinstance(temp, six.binary_type):
+ raise TypeError("Blob data should be of type bytes.")
+ data += temp or b""
+
+ # We have read an empty string and so are at the end
+ # of the buffer or we have read a full chunk.
+ if temp == b"" or len(data) == self.chunk_size:
+ break
+
+ if len(data) == self.chunk_size:
+ if self.padder:
+ data = self.padder.update(data)
+ if self.encryptor:
+ data = self.encryptor.update(data)
+ yield index, data
+ else:
+ if self.padder:
+ data = self.padder.update(data) + self.padder.finalize()
+ if self.encryptor:
+ data = self.encryptor.update(data) + self.encryptor.finalize()
+ if data:
+ yield index, data
+ break
+ index += len(data)
+
+ def process_chunk(self, chunk_data):
+ chunk_bytes = chunk_data[1]
+ chunk_offset = chunk_data[0]
+ return self._upload_chunk_with_progress(chunk_offset, chunk_bytes)
+
+ def _update_progress(self, length):
+ if self.progress_lock is not None:
+ with self.progress_lock:
+ self.progress_total += length
+ else:
+ self.progress_total += length
+
+ def _upload_chunk(self, chunk_offset, chunk_data):
+ raise NotImplementedError("Must be implemented by child class.")
+
+ def _upload_chunk_with_progress(self, chunk_offset, chunk_data):
+ range_id = self._upload_chunk(chunk_offset, chunk_data)
+ self._update_progress(len(chunk_data))
+ return range_id
+
+ def get_substream_blocks(self):
+ assert self.chunk_size is not None
+ lock = self.stream_lock
+ blob_length = self.total_size
+
+ if blob_length is None:
+ blob_length = get_length(self.stream)
+ if blob_length is None:
+ raise ValueError("Unable to determine content length of upload data.")
+
+ blocks = int(ceil(blob_length / (self.chunk_size * 1.0)))
+ last_block_size = self.chunk_size if blob_length % self.chunk_size == 0 else blob_length % self.chunk_size
+
+ for i in range(blocks):
+ index = i * self.chunk_size
+ length = last_block_size if i == blocks - 1 else self.chunk_size
+ yield index, SubStream(self.stream, index, length, lock)
+
+ def process_substream_block(self, block_data):
+ return self._upload_substream_block_with_progress(block_data[0], block_data[1])
+
+ def _upload_substream_block(self, index, block_stream):
+ raise NotImplementedError("Must be implemented by child class.")
+
+ def _upload_substream_block_with_progress(self, index, block_stream):
+ range_id = self._upload_substream_block(index, block_stream)
+ self._update_progress(len(block_stream))
+ return range_id
+
+ def set_response_properties(self, resp):
+ self.etag = resp.etag
+ self.last_modified = resp.last_modified
+
+
+class BlockBlobChunkUploader(_ChunkUploader):
+
+ def __init__(self, *args, **kwargs):
+ kwargs.pop("modified_access_conditions", None)
+ super(BlockBlobChunkUploader, self).__init__(*args, **kwargs)
+ self.current_length = None
+
+ def _upload_chunk(self, chunk_offset, chunk_data):
+ # TODO: This is incorrect, but works with recording.
+ index = '{0:032d}'.format(chunk_offset)
+ block_id = encode_base64(url_quote(encode_base64(index)))
+ self.service.stage_block(
+ block_id,
+ len(chunk_data),
+ chunk_data,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+ return index, block_id
+
+ def _upload_substream_block(self, index, block_stream):
+ try:
+ block_id = 'BlockId{}'.format("%05d" % (index/self.chunk_size))
+ self.service.stage_block(
+ block_id,
+ len(block_stream),
+ block_stream,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+ finally:
+ block_stream.close()
+ return block_id
+
+
+class PageBlobChunkUploader(_ChunkUploader): # pylint: disable=abstract-method
+
+ def _is_chunk_empty(self, chunk_data):
+ # read until non-zero byte is encountered
+ # if reached the end without returning, then chunk_data is all 0's
+ return not any(bytearray(chunk_data))
+
+ def _upload_chunk(self, chunk_offset, chunk_data):
+ # avoid uploading the empty pages
+ if not self._is_chunk_empty(chunk_data):
+ chunk_end = chunk_offset + len(chunk_data) - 1
+ content_range = "bytes={0}-{1}".format(chunk_offset, chunk_end)
+ computed_md5 = None
+ self.response_headers = self.service.upload_pages(
+ body=chunk_data,
+ content_length=len(chunk_data),
+ transactional_content_md5=computed_md5,
+ range=content_range,
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+
+ if not self.parallel and self.request_options.get('modified_access_conditions'):
+ self.request_options['modified_access_conditions'].if_match = self.response_headers['etag']
+
+ def _upload_substream_block(self, index, block_stream):
+ pass
+
+
+class AppendBlobChunkUploader(_ChunkUploader): # pylint: disable=abstract-method
+
+ def __init__(self, *args, **kwargs):
+ super(AppendBlobChunkUploader, self).__init__(*args, **kwargs)
+ self.current_length = None
+
+ def _upload_chunk(self, chunk_offset, chunk_data):
+ if self.current_length is None:
+ self.response_headers = self.service.append_block(
+ body=chunk_data,
+ content_length=len(chunk_data),
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+ self.current_length = int(self.response_headers["blob_append_offset"])
+ else:
+ self.request_options['append_position_access_conditions'].append_position = \
+ self.current_length + chunk_offset
+ self.response_headers = self.service.append_block(
+ body=chunk_data,
+ content_length=len(chunk_data),
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+
+ def _upload_substream_block(self, index, block_stream):
+ pass
+
+
+class DataLakeFileChunkUploader(_ChunkUploader): # pylint: disable=abstract-method
+
+ def _upload_chunk(self, chunk_offset, chunk_data):
+ # avoid uploading the empty pages
+ self.response_headers = self.service.append_data(
+ body=chunk_data,
+ position=chunk_offset,
+ content_length=len(chunk_data),
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+
+ if not self.parallel and self.request_options.get('modified_access_conditions'):
+ self.request_options['modified_access_conditions'].if_match = self.response_headers['etag']
+
+ def _upload_substream_block(self, index, block_stream):
+ try:
+ self.service.append_data(
+ body=block_stream,
+ position=index,
+ content_length=len(block_stream),
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+ finally:
+ block_stream.close()
+
+
+class FileChunkUploader(_ChunkUploader): # pylint: disable=abstract-method
+
+ def _upload_chunk(self, chunk_offset, chunk_data):
+ length = len(chunk_data)
+ chunk_end = chunk_offset + length - 1
+ response = self.service.upload_range(
+ chunk_data,
+ chunk_offset,
+ length,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+ return 'bytes={0}-{1}'.format(chunk_offset, chunk_end), response
+
+ # TODO: Implement this method.
+ def _upload_substream_block(self, index, block_stream):
+ pass
+
+
+class SubStream(IOBase):
+
+ def __init__(self, wrapped_stream, stream_begin_index, length, lockObj):
+ # Python 2.7: file-like objects created with open() typically support seek(), but are not
+ # derivations of io.IOBase and thus do not implement seekable().
+ # Python > 3.0: file-like objects created with open() are derived from io.IOBase.
+ try:
+ # only the main thread runs this, so there's no need grabbing the lock
+ wrapped_stream.seek(0, SEEK_CUR)
+ except:
+ raise ValueError("Wrapped stream must support seek().")
+
+ self._lock = lockObj
+ self._wrapped_stream = wrapped_stream
+ self._position = 0
+ self._stream_begin_index = stream_begin_index
+ self._length = length
+ self._buffer = BytesIO()
+
+ # we must avoid buffering more than necessary, and also not use up too much memory
+ # so the max buffer size is capped at 4MB
+ self._max_buffer_size = (
+ length if length < _LARGE_BLOB_UPLOAD_MAX_READ_BUFFER_SIZE else _LARGE_BLOB_UPLOAD_MAX_READ_BUFFER_SIZE
+ )
+ self._current_buffer_start = 0
+ self._current_buffer_size = 0
+ super(SubStream, self).__init__()
+
+ def __len__(self):
+ return self._length
+
+ def close(self):
+ if self._buffer:
+ self._buffer.close()
+ self._wrapped_stream = None
+ IOBase.close(self)
+
+ def fileno(self):
+ return self._wrapped_stream.fileno()
+
+ def flush(self):
+ pass
+
+ def read(self, size=None):
+ if self.closed: # pylint: disable=using-constant-test
+ raise ValueError("Stream is closed.")
+
+ if size is None:
+ size = self._length - self._position
+
+ # adjust if out of bounds
+ if size + self._position >= self._length:
+ size = self._length - self._position
+
+ # return fast
+ if size == 0 or self._buffer.closed:
+ return b""
+
+ # attempt first read from the read buffer and update position
+ read_buffer = self._buffer.read(size)
+ bytes_read = len(read_buffer)
+ bytes_remaining = size - bytes_read
+ self._position += bytes_read
+
+ # repopulate the read buffer from the underlying stream to fulfill the request
+ # ensure the seek and read operations are done atomically (only if a lock is provided)
+ if bytes_remaining > 0:
+ with self._buffer:
+ # either read in the max buffer size specified on the class
+ # or read in just enough data for the current block/sub stream
+ current_max_buffer_size = min(self._max_buffer_size, self._length - self._position)
+
+ # lock is only defined if max_concurrency > 1 (parallel uploads)
+ if self._lock:
+ with self._lock:
+ # reposition the underlying stream to match the start of the data to read
+ absolute_position = self._stream_begin_index + self._position
+ self._wrapped_stream.seek(absolute_position, SEEK_SET)
+ # If we can't seek to the right location, our read will be corrupted so fail fast.
+ if self._wrapped_stream.tell() != absolute_position:
+ raise IOError("Stream failed to seek to the desired location.")
+ buffer_from_stream = self._wrapped_stream.read(current_max_buffer_size)
+ else:
+ absolute_position = self._stream_begin_index + self._position
+ # It's possible that there's connection problem during data transfer,
+ # so when we retry we don't want to read from current position of wrapped stream,
+ # instead we should seek to where we want to read from.
+ if self._wrapped_stream.tell() != absolute_position:
+ self._wrapped_stream.seek(absolute_position, SEEK_SET)
+
+ buffer_from_stream = self._wrapped_stream.read(current_max_buffer_size)
+
+ if buffer_from_stream:
+ # update the buffer with new data from the wrapped stream
+ # we need to note down the start position and size of the buffer, in case seek is performed later
+ self._buffer = BytesIO(buffer_from_stream)
+ self._current_buffer_start = self._position
+ self._current_buffer_size = len(buffer_from_stream)
+
+ # read the remaining bytes from the new buffer and update position
+ second_read_buffer = self._buffer.read(bytes_remaining)
+ read_buffer += second_read_buffer
+ self._position += len(second_read_buffer)
+
+ return read_buffer
+
+ def readable(self):
+ return True
+
+ def readinto(self, b):
+ raise UnsupportedOperation
+
+ def seek(self, offset, whence=0):
+ if whence is SEEK_SET:
+ start_index = 0
+ elif whence is SEEK_CUR:
+ start_index = self._position
+ elif whence is SEEK_END:
+ start_index = self._length
+ offset = -offset
+ else:
+ raise ValueError("Invalid argument for the 'whence' parameter.")
+
+ pos = start_index + offset
+
+ if pos > self._length:
+ pos = self._length
+ elif pos < 0:
+ pos = 0
+
+ # check if buffer is still valid
+ # if not, drop buffer
+ if pos < self._current_buffer_start or pos >= self._current_buffer_start + self._current_buffer_size:
+ self._buffer.close()
+ self._buffer = BytesIO()
+ else: # if yes seek to correct position
+ delta = pos - self._current_buffer_start
+ self._buffer.seek(delta, SEEK_SET)
+
+ self._position = pos
+ return pos
+
+ def seekable(self):
+ return True
+
+ def tell(self):
+ return self._position
+
+ def write(self):
+ raise UnsupportedOperation
+
+ def writelines(self):
+ raise UnsupportedOperation
+
+ def writeable(self):
+ return False
+
+
+class IterStreamer(object):
+ """
+ File-like streaming iterator.
+ """
+
+ def __init__(self, generator, encoding="UTF-8"):
+ self.generator = generator
+ self.iterator = iter(generator)
+ self.leftover = b""
+ self.encoding = encoding
+
+ def __len__(self):
+ return self.generator.__len__()
+
+ def __iter__(self):
+ return self.iterator
+
+ def seekable(self):
+ return False
+
+ def __next__(self):
+ return next(self.iterator)
+
+ next = __next__ # Python 2 compatibility.
+
+ def tell(self, *args, **kwargs):
+ raise UnsupportedOperation("Data generator does not support tell.")
+
+ def seek(self, *args, **kwargs):
+ raise UnsupportedOperation("Data generator is unseekable.")
+
+ def read(self, size):
+ data = self.leftover
+ count = len(self.leftover)
+ try:
+ while count < size:
+ chunk = self.__next__()
+ if isinstance(chunk, six.text_type):
+ chunk = chunk.encode(self.encoding)
+ data += chunk
+ count += len(chunk)
+ # This means count < size and what's leftover will be returned in this call.
+ except StopIteration:
+ self.leftover = b""
+
+ if count >= size:
+ self.leftover = data[size:]
+
+ return data[:size]
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/uploads_async.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/uploads_async.py
new file mode 100644
index 00000000000..5ed192b3659
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared/uploads_async.py
@@ -0,0 +1,395 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=no-self-use
+
+import asyncio
+from asyncio import Lock
+from itertools import islice
+import threading
+
+from math import ceil
+
+import six
+
+from . import encode_base64, url_quote
+from .request_handlers import get_length
+from .response_handlers import return_response_headers
+from .encryption import get_blob_encryptor_and_padder
+from .uploads import SubStream, IterStreamer # pylint: disable=unused-import
+
+
+_LARGE_BLOB_UPLOAD_MAX_READ_BUFFER_SIZE = 4 * 1024 * 1024
+_ERROR_VALUE_SHOULD_BE_SEEKABLE_STREAM = '{0} should be a seekable file-like/io.IOBase type stream object.'
+
+
+async def _parallel_uploads(uploader, pending, running):
+ range_ids = []
+ while True:
+ # Wait for some download to finish before adding a new one
+ done, running = await asyncio.wait(running, return_when=asyncio.FIRST_COMPLETED)
+ range_ids.extend([chunk.result() for chunk in done])
+ try:
+ for _ in range(0, len(done)):
+ next_chunk = next(pending)
+ running.add(asyncio.ensure_future(uploader(next_chunk)))
+ except StopIteration:
+ break
+
+ # Wait for the remaining uploads to finish
+ if running:
+ done, _running = await asyncio.wait(running)
+ range_ids.extend([chunk.result() for chunk in done])
+ return range_ids
+
+
+async def upload_data_chunks(
+ service=None,
+ uploader_class=None,
+ total_size=None,
+ chunk_size=None,
+ max_concurrency=None,
+ stream=None,
+ encryption_options=None,
+ **kwargs):
+
+ if encryption_options:
+ encryptor, padder = get_blob_encryptor_and_padder(
+ encryption_options.get('cek'),
+ encryption_options.get('vector'),
+ uploader_class is not PageBlobChunkUploader)
+ kwargs['encryptor'] = encryptor
+ kwargs['padder'] = padder
+
+ parallel = max_concurrency > 1
+ if parallel and 'modified_access_conditions' in kwargs:
+ # Access conditions do not work with parallelism
+ kwargs['modified_access_conditions'] = None
+
+ uploader = uploader_class(
+ service=service,
+ total_size=total_size,
+ chunk_size=chunk_size,
+ stream=stream,
+ parallel=parallel,
+ **kwargs)
+
+ if parallel:
+ upload_tasks = uploader.get_chunk_streams()
+ running_futures = [
+ asyncio.ensure_future(uploader.process_chunk(u))
+ for u in islice(upload_tasks, 0, max_concurrency)
+ ]
+ range_ids = await _parallel_uploads(uploader.process_chunk, upload_tasks, running_futures)
+ else:
+ range_ids = []
+ for chunk in uploader.get_chunk_streams():
+ range_ids.append(await uploader.process_chunk(chunk))
+
+ if any(range_ids):
+ return [r[1] for r in sorted(range_ids, key=lambda r: r[0])]
+ return uploader.response_headers
+
+
+async def upload_substream_blocks(
+ service=None,
+ uploader_class=None,
+ total_size=None,
+ chunk_size=None,
+ max_concurrency=None,
+ stream=None,
+ **kwargs):
+ parallel = max_concurrency > 1
+ if parallel and 'modified_access_conditions' in kwargs:
+ # Access conditions do not work with parallelism
+ kwargs['modified_access_conditions'] = None
+ uploader = uploader_class(
+ service=service,
+ total_size=total_size,
+ chunk_size=chunk_size,
+ stream=stream,
+ parallel=parallel,
+ **kwargs)
+
+ if parallel:
+ upload_tasks = uploader.get_substream_blocks()
+ running_futures = [
+ asyncio.ensure_future(uploader.process_substream_block(u))
+ for u in islice(upload_tasks, 0, max_concurrency)
+ ]
+ range_ids = await _parallel_uploads(uploader.process_substream_block, upload_tasks, running_futures)
+ else:
+ range_ids = []
+ for block in uploader.get_substream_blocks():
+ range_ids.append(await uploader.process_substream_block(block))
+ if any(range_ids):
+ return sorted(range_ids)
+ return
+
+
+class _ChunkUploader(object): # pylint: disable=too-many-instance-attributes
+
+ def __init__(self, service, total_size, chunk_size, stream, parallel, encryptor=None, padder=None, **kwargs):
+ self.service = service
+ self.total_size = total_size
+ self.chunk_size = chunk_size
+ self.stream = stream
+ self.parallel = parallel
+
+ # Stream management
+ self.stream_start = stream.tell() if parallel else None
+ self.stream_lock = threading.Lock() if parallel else None
+
+ # Progress feedback
+ self.progress_total = 0
+ self.progress_lock = Lock() if parallel else None
+
+ # Encryption
+ self.encryptor = encryptor
+ self.padder = padder
+ self.response_headers = None
+ self.etag = None
+ self.last_modified = None
+ self.request_options = kwargs
+
+ def get_chunk_streams(self):
+ index = 0
+ while True:
+ data = b''
+ read_size = self.chunk_size
+
+ # Buffer until we either reach the end of the stream or get a whole chunk.
+ while True:
+ if self.total_size:
+ read_size = min(self.chunk_size - len(data), self.total_size - (index + len(data)))
+ temp = self.stream.read(read_size)
+ if not isinstance(temp, six.binary_type):
+ raise TypeError('Blob data should be of type bytes.')
+ data += temp or b""
+
+ # We have read an empty string and so are at the end
+ # of the buffer or we have read a full chunk.
+ if temp == b'' or len(data) == self.chunk_size:
+ break
+
+ if len(data) == self.chunk_size:
+ if self.padder:
+ data = self.padder.update(data)
+ if self.encryptor:
+ data = self.encryptor.update(data)
+ yield index, data
+ else:
+ if self.padder:
+ data = self.padder.update(data) + self.padder.finalize()
+ if self.encryptor:
+ data = self.encryptor.update(data) + self.encryptor.finalize()
+ if data:
+ yield index, data
+ break
+ index += len(data)
+
+ async def process_chunk(self, chunk_data):
+ chunk_bytes = chunk_data[1]
+ chunk_offset = chunk_data[0]
+ return await self._upload_chunk_with_progress(chunk_offset, chunk_bytes)
+
+ async def _update_progress(self, length):
+ if self.progress_lock is not None:
+ async with self.progress_lock:
+ self.progress_total += length
+ else:
+ self.progress_total += length
+
+ async def _upload_chunk(self, chunk_offset, chunk_data):
+ raise NotImplementedError("Must be implemented by child class.")
+
+ async def _upload_chunk_with_progress(self, chunk_offset, chunk_data):
+ range_id = await self._upload_chunk(chunk_offset, chunk_data)
+ await self._update_progress(len(chunk_data))
+ return range_id
+
+ def get_substream_blocks(self):
+ assert self.chunk_size is not None
+ lock = self.stream_lock
+ blob_length = self.total_size
+
+ if blob_length is None:
+ blob_length = get_length(self.stream)
+ if blob_length is None:
+ raise ValueError("Unable to determine content length of upload data.")
+
+ blocks = int(ceil(blob_length / (self.chunk_size * 1.0)))
+ last_block_size = self.chunk_size if blob_length % self.chunk_size == 0 else blob_length % self.chunk_size
+
+ for i in range(blocks):
+ index = i * self.chunk_size
+ length = last_block_size if i == blocks - 1 else self.chunk_size
+ yield index, SubStream(self.stream, index, length, lock)
+
+ async def process_substream_block(self, block_data):
+ return await self._upload_substream_block_with_progress(block_data[0], block_data[1])
+
+ async def _upload_substream_block(self, index, block_stream):
+ raise NotImplementedError("Must be implemented by child class.")
+
+ async def _upload_substream_block_with_progress(self, index, block_stream):
+ range_id = await self._upload_substream_block(index, block_stream)
+ await self._update_progress(len(block_stream))
+ return range_id
+
+ def set_response_properties(self, resp):
+ self.etag = resp.etag
+ self.last_modified = resp.last_modified
+
+
+class BlockBlobChunkUploader(_ChunkUploader):
+
+ def __init__(self, *args, **kwargs):
+ kwargs.pop('modified_access_conditions', None)
+ super(BlockBlobChunkUploader, self).__init__(*args, **kwargs)
+ self.current_length = None
+
+ async def _upload_chunk(self, chunk_offset, chunk_data):
+ # TODO: This is incorrect, but works with recording.
+ index = '{0:032d}'.format(chunk_offset)
+ block_id = encode_base64(url_quote(encode_base64(index)))
+ await self.service.stage_block(
+ block_id,
+ len(chunk_data),
+ body=chunk_data,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options)
+ return index, block_id
+
+ async def _upload_substream_block(self, index, block_stream):
+ try:
+ block_id = 'BlockId{}'.format("%05d" % (index/self.chunk_size))
+ await self.service.stage_block(
+ block_id,
+ len(block_stream),
+ block_stream,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options)
+ finally:
+ block_stream.close()
+ return block_id
+
+
+class PageBlobChunkUploader(_ChunkUploader): # pylint: disable=abstract-method
+
+ def _is_chunk_empty(self, chunk_data):
+ # read until non-zero byte is encountered
+ # if reached the end without returning, then chunk_data is all 0's
+ for each_byte in chunk_data:
+ if each_byte not in [0, b'\x00']:
+ return False
+ return True
+
+ async def _upload_chunk(self, chunk_offset, chunk_data):
+ # avoid uploading the empty pages
+ if not self._is_chunk_empty(chunk_data):
+ chunk_end = chunk_offset + len(chunk_data) - 1
+ content_range = 'bytes={0}-{1}'.format(chunk_offset, chunk_end)
+ computed_md5 = None
+ self.response_headers = await self.service.upload_pages(
+ body=chunk_data,
+ content_length=len(chunk_data),
+ transactional_content_md5=computed_md5,
+ range=content_range,
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options)
+
+ if not self.parallel and self.request_options.get('modified_access_conditions'):
+ self.request_options['modified_access_conditions'].if_match = self.response_headers['etag']
+
+ async def _upload_substream_block(self, index, block_stream):
+ pass
+
+
+class AppendBlobChunkUploader(_ChunkUploader): # pylint: disable=abstract-method
+
+ def __init__(self, *args, **kwargs):
+ super(AppendBlobChunkUploader, self).__init__(*args, **kwargs)
+ self.current_length = None
+
+ async def _upload_chunk(self, chunk_offset, chunk_data):
+ if self.current_length is None:
+ self.response_headers = await self.service.append_block(
+ body=chunk_data,
+ content_length=len(chunk_data),
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options)
+ self.current_length = int(self.response_headers['blob_append_offset'])
+ else:
+ self.request_options['append_position_access_conditions'].append_position = \
+ self.current_length + chunk_offset
+ self.response_headers = await self.service.append_block(
+ body=chunk_data,
+ content_length=len(chunk_data),
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options)
+
+ async def _upload_substream_block(self, index, block_stream):
+ pass
+
+
+class DataLakeFileChunkUploader(_ChunkUploader): # pylint: disable=abstract-method
+
+ async def _upload_chunk(self, chunk_offset, chunk_data):
+ self.response_headers = await self.service.append_data(
+ body=chunk_data,
+ position=chunk_offset,
+ content_length=len(chunk_data),
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+
+ if not self.parallel and self.request_options.get('modified_access_conditions'):
+ self.request_options['modified_access_conditions'].if_match = self.response_headers['etag']
+
+ async def _upload_substream_block(self, index, block_stream):
+ try:
+ await self.service.append_data(
+ body=block_stream,
+ position=index,
+ content_length=len(block_stream),
+ cls=return_response_headers,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+ finally:
+ block_stream.close()
+
+
+class FileChunkUploader(_ChunkUploader): # pylint: disable=abstract-method
+
+ async def _upload_chunk(self, chunk_offset, chunk_data):
+ length = len(chunk_data)
+ chunk_end = chunk_offset + length - 1
+ response = await self.service.upload_range(
+ chunk_data,
+ chunk_offset,
+ length,
+ data_stream_total=self.total_size,
+ upload_stream_current=self.progress_total,
+ **self.request_options
+ )
+ range_id = 'bytes={0}-{1}'.format(chunk_offset, chunk_end)
+ return range_id, response
+
+ # TODO: Implement this method.
+ async def _upload_substream_block(self, index, block_stream):
+ pass
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared_access_signature.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared_access_signature.py
new file mode 100644
index 00000000000..e3f1b248250
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_shared_access_signature.py
@@ -0,0 +1,609 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+from typing import ( # pylint: disable=unused-import
+ Union, Optional, Any, TYPE_CHECKING
+)
+
+from ._shared import sign_string, url_quote
+from ._shared.constants import X_MS_VERSION
+from ._shared.models import Services, UserDelegationKey
+from ._shared.shared_access_signature import SharedAccessSignature, _SharedAccessHelper, \
+ QueryStringConstants
+
+if TYPE_CHECKING:
+ from datetime import datetime
+ from ..blob import (
+ ResourceTypes,
+ AccountSasPermissions,
+ ContainerSasPermissions,
+ BlobSasPermissions
+ )
+
+
+class BlobQueryStringConstants(object):
+ SIGNED_TIMESTAMP = 'snapshot'
+
+
+class BlobSharedAccessSignature(SharedAccessSignature):
+ '''
+ Provides a factory for creating blob and container access
+ signature tokens with a common account name and account key. Users can either
+ use the factory or can construct the appropriate service and use the
+ generate_*_shared_access_signature method directly.
+ '''
+
+ def __init__(self, account_name, account_key=None, user_delegation_key=None):
+ '''
+ :param str account_name:
+ The storage account name used to generate the shared access signatures.
+ :param str account_key:
+ The access key to generate the shares access signatures.
+ :param ~azure.storage.blob.models.UserDelegationKey user_delegation_key:
+ Instead of an account key, the user could pass in a user delegation key.
+ A user delegation key can be obtained from the service by authenticating with an AAD identity;
+ this can be accomplished by calling get_user_delegation_key on any Blob service object.
+ '''
+ super(BlobSharedAccessSignature, self).__init__(account_name, account_key, x_ms_version=X_MS_VERSION)
+ self.user_delegation_key = user_delegation_key
+
+ def generate_blob(self, container_name, blob_name, snapshot=None, version_id=None, permission=None,
+ expiry=None, start=None, policy_id=None, ip=None, protocol=None,
+ cache_control=None, content_disposition=None,
+ content_encoding=None, content_language=None,
+ content_type=None, **kwargs):
+ '''
+ Generates a shared access signature for the blob or one of its snapshots.
+ Use the returned signature with the sas_token parameter of any BlobService.
+
+ :param str container_name:
+ Name of container.
+ :param str blob_name:
+ Name of blob.
+ :param str snapshot:
+ The snapshot parameter is an opaque DateTime value that,
+ when present, specifies the blob snapshot to grant permission.
+ :param permission:
+ The permissions associated with the shared access signature. The
+ user is restricted to operations allowed by the permissions.
+ Permissions must be ordered racwdxytmei.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has been
+ specified in an associated stored access policy.
+ :type permission: str or BlobSasPermissions
+ :param expiry:
+ The time at which the shared access signature becomes invalid.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has
+ been specified in an associated stored access policy. Azure will always
+ convert values to UTC. If a date is passed in without timezone info, it
+ is assumed to be UTC.
+ :type expiry: datetime or str
+ :param start:
+ The time at which the shared access signature becomes valid. If
+ omitted, start time for this call is assumed to be the time when the
+ storage service receives the request. Azure will always convert values
+ to UTC. If a date is passed in without timezone info, it is assumed to
+ be UTC.
+ :type start: datetime or str
+ :param str policy_id:
+ A unique value up to 64 characters in length that correlates to a
+ stored access policy. To create a stored access policy, use
+ set_blob_service_properties.
+ :param str ip:
+ Specifies an IP address or a range of IP addresses from which to accept requests.
+ If the IP address from which the request originates does not match the IP address
+ or address range specified on the SAS token, the request is not authenticated.
+ For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS
+ restricts the request to those IP addresses.
+ :param str protocol:
+ Specifies the protocol permitted for a request made. The default value
+ is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values.
+ :param str cache_control:
+ Response header value for Cache-Control when resource is accessed
+ using this shared access signature.
+ :param str content_disposition:
+ Response header value for Content-Disposition when resource is accessed
+ using this shared access signature.
+ :param str content_encoding:
+ Response header value for Content-Encoding when resource is accessed
+ using this shared access signature.
+ :param str content_language:
+ Response header value for Content-Language when resource is accessed
+ using this shared access signature.
+ :param str content_type:
+ Response header value for Content-Type when resource is accessed
+ using this shared access signature.
+ '''
+ resource_path = container_name + '/' + blob_name
+
+ sas = _BlobSharedAccessHelper()
+ sas.add_base(permission, expiry, start, ip, protocol, self.x_ms_version)
+ sas.add_id(policy_id)
+
+ resource = 'bs' if snapshot else 'b'
+ resource = 'bv' if version_id else resource
+ resource = 'd' if kwargs.pop("is_directory", None) else resource
+ sas.add_resource(resource)
+
+ sas.add_timestamp(snapshot or version_id)
+ sas.add_override_response_headers(cache_control, content_disposition,
+ content_encoding, content_language,
+ content_type)
+ sas.add_encryption_scope(**kwargs)
+ sas.add_info_for_hns_account(**kwargs)
+ sas.add_resource_signature(self.account_name, self.account_key, resource_path,
+ user_delegation_key=self.user_delegation_key)
+
+ return sas.get_token()
+
+ def generate_container(self, container_name, permission=None, expiry=None,
+ start=None, policy_id=None, ip=None, protocol=None,
+ cache_control=None, content_disposition=None,
+ content_encoding=None, content_language=None,
+ content_type=None, **kwargs):
+ '''
+ Generates a shared access signature for the container.
+ Use the returned signature with the sas_token parameter of any BlobService.
+
+ :param str container_name:
+ Name of container.
+ :param permission:
+ The permissions associated with the shared access signature. The
+ user is restricted to operations allowed by the permissions.
+ Permissions must be ordered racwdxyltfmei.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has been
+ specified in an associated stored access policy.
+ :type permission: str or ContainerSasPermissions
+ :param expiry:
+ The time at which the shared access signature becomes invalid.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has
+ been specified in an associated stored access policy. Azure will always
+ convert values to UTC. If a date is passed in without timezone info, it
+ is assumed to be UTC.
+ :type expiry: datetime or str
+ :param start:
+ The time at which the shared access signature becomes valid. If
+ omitted, start time for this call is assumed to be the time when the
+ storage service receives the request. Azure will always convert values
+ to UTC. If a date is passed in without timezone info, it is assumed to
+ be UTC.
+ :type start: datetime or str
+ :param str policy_id:
+ A unique value up to 64 characters in length that correlates to a
+ stored access policy. To create a stored access policy, use
+ set_blob_service_properties.
+ :param str ip:
+ Specifies an IP address or a range of IP addresses from which to accept requests.
+ If the IP address from which the request originates does not match the IP address
+ or address range specified on the SAS token, the request is not authenticated.
+ For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS
+ restricts the request to those IP addresses.
+ :param str protocol:
+ Specifies the protocol permitted for a request made. The default value
+ is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values.
+ :param str cache_control:
+ Response header value for Cache-Control when resource is accessed
+ using this shared access signature.
+ :param str content_disposition:
+ Response header value for Content-Disposition when resource is accessed
+ using this shared access signature.
+ :param str content_encoding:
+ Response header value for Content-Encoding when resource is accessed
+ using this shared access signature.
+ :param str content_language:
+ Response header value for Content-Language when resource is accessed
+ using this shared access signature.
+ :param str content_type:
+ Response header value for Content-Type when resource is accessed
+ using this shared access signature.
+ '''
+ sas = _BlobSharedAccessHelper()
+ sas.add_base(permission, expiry, start, ip, protocol, self.x_ms_version)
+ sas.add_id(policy_id)
+ sas.add_resource('c')
+ sas.add_override_response_headers(cache_control, content_disposition,
+ content_encoding, content_language,
+ content_type)
+ sas.add_encryption_scope(**kwargs)
+ sas.add_info_for_hns_account(**kwargs)
+ sas.add_resource_signature(self.account_name, self.account_key, container_name,
+ user_delegation_key=self.user_delegation_key)
+ return sas.get_token()
+
+
+class _BlobSharedAccessHelper(_SharedAccessHelper):
+
+ def add_timestamp(self, timestamp):
+ self._add_query(BlobQueryStringConstants.SIGNED_TIMESTAMP, timestamp)
+
+ def add_info_for_hns_account(self, **kwargs):
+ self._add_query(QueryStringConstants.SIGNED_DIRECTORY_DEPTH, kwargs.pop('sdd', None))
+ self._add_query(QueryStringConstants.SIGNED_AUTHORIZED_OID, kwargs.pop('preauthorized_agent_object_id', None))
+ self._add_query(QueryStringConstants.SIGNED_UNAUTHORIZED_OID, kwargs.pop('agent_object_id', None))
+ self._add_query(QueryStringConstants.SIGNED_CORRELATION_ID, kwargs.pop('correlation_id', None))
+
+ def get_value_to_append(self, query):
+ return_value = self.query_dict.get(query) or ''
+ return return_value + '\n'
+
+ def add_resource_signature(self, account_name, account_key, path, user_delegation_key=None):
+ # pylint: disable = no-member
+ if path[0] != '/':
+ path = '/' + path
+
+ canonicalized_resource = '/blob/' + account_name + path + '\n'
+
+ # Form the string to sign from shared_access_policy and canonicalized
+ # resource. The order of values is important.
+ string_to_sign = \
+ (self.get_value_to_append(QueryStringConstants.SIGNED_PERMISSION) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_START) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_EXPIRY) +
+ canonicalized_resource)
+
+ if user_delegation_key is not None:
+ self._add_query(QueryStringConstants.SIGNED_OID, user_delegation_key.signed_oid)
+ self._add_query(QueryStringConstants.SIGNED_TID, user_delegation_key.signed_tid)
+ self._add_query(QueryStringConstants.SIGNED_KEY_START, user_delegation_key.signed_start)
+ self._add_query(QueryStringConstants.SIGNED_KEY_EXPIRY, user_delegation_key.signed_expiry)
+ self._add_query(QueryStringConstants.SIGNED_KEY_SERVICE, user_delegation_key.signed_service)
+ self._add_query(QueryStringConstants.SIGNED_KEY_VERSION, user_delegation_key.signed_version)
+
+ string_to_sign += \
+ (self.get_value_to_append(QueryStringConstants.SIGNED_OID) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_TID) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_KEY_START) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_KEY_EXPIRY) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_KEY_SERVICE) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_KEY_VERSION) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_AUTHORIZED_OID) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_UNAUTHORIZED_OID) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_CORRELATION_ID))
+ else:
+ string_to_sign += self.get_value_to_append(QueryStringConstants.SIGNED_IDENTIFIER)
+
+ string_to_sign += \
+ (self.get_value_to_append(QueryStringConstants.SIGNED_IP) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_PROTOCOL) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_VERSION) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_RESOURCE) +
+ self.get_value_to_append(BlobQueryStringConstants.SIGNED_TIMESTAMP) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_ENCRYPTION_SCOPE) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_CACHE_CONTROL) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_CONTENT_DISPOSITION) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_CONTENT_ENCODING) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_CONTENT_LANGUAGE) +
+ self.get_value_to_append(QueryStringConstants.SIGNED_CONTENT_TYPE))
+
+ # remove the trailing newline
+ if string_to_sign[-1] == '\n':
+ string_to_sign = string_to_sign[:-1]
+
+ self._add_query(QueryStringConstants.SIGNED_SIGNATURE,
+ sign_string(account_key if user_delegation_key is None else user_delegation_key.value,
+ string_to_sign))
+
+ def get_token(self):
+ # a conscious decision was made to exclude the timestamp in the generated token
+ # this is to avoid having two snapshot ids in the query parameters when the user appends the snapshot timestamp
+ exclude = [BlobQueryStringConstants.SIGNED_TIMESTAMP]
+ return '&'.join(['{0}={1}'.format(n, url_quote(v))
+ for n, v in self.query_dict.items() if v is not None and n not in exclude])
+
+
+def generate_account_sas(
+ account_name, # type: str
+ account_key, # type: str
+ resource_types, # type: Union[ResourceTypes, str]
+ permission, # type: Union[AccountSasPermissions, str]
+ expiry, # type: Optional[Union[datetime, str]]
+ start=None, # type: Optional[Union[datetime, str]]
+ ip=None, # type: Optional[str]
+ **kwargs # type: Any
+ ): # type: (...) -> str
+ """Generates a shared access signature for the blob service.
+
+ Use the returned signature with the credential parameter of any BlobServiceClient,
+ ContainerClient or BlobClient.
+
+ :param str account_name:
+ The storage account name used to generate the shared access signature.
+ :param str account_key:
+ The account key, also called shared key or access key, to generate the shared access signature.
+ :param resource_types:
+ Specifies the resource types that are accessible with the account SAS.
+ :type resource_types: str or ~azure.storage.blob.ResourceTypes
+ :param permission:
+ The permissions associated with the shared access signature. The
+ user is restricted to operations allowed by the permissions.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has been
+ specified in an associated stored access policy.
+ :type permission: str or ~azure.storage.blob.AccountSasPermissions
+ :param expiry:
+ The time at which the shared access signature becomes invalid.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has
+ been specified in an associated stored access policy. Azure will always
+ convert values to UTC. If a date is passed in without timezone info, it
+ is assumed to be UTC.
+ :type expiry: ~datetime.datetime or str
+ :param start:
+ The time at which the shared access signature becomes valid. If
+ omitted, start time for this call is assumed to be the time when the
+ storage service receives the request. Azure will always convert values
+ to UTC. If a date is passed in without timezone info, it is assumed to
+ be UTC.
+ :type start: ~datetime.datetime or str
+ :param str ip:
+ Specifies an IP address or a range of IP addresses from which to accept requests.
+ If the IP address from which the request originates does not match the IP address
+ or address range specified on the SAS token, the request is not authenticated.
+ For example, specifying ip=168.1.5.65 or ip=168.1.5.60-168.1.5.70 on the SAS
+ restricts the request to those IP addresses.
+ :keyword str protocol:
+ Specifies the protocol permitted for a request made. The default value is https.
+ :keyword str encryption_scope:
+ Specifies the encryption scope for a request made so that all write operations will be service encrypted.
+ :return: A Shared Access Signature (sas) token.
+ :rtype: str
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_authentication.py
+ :start-after: [START create_sas_token]
+ :end-before: [END create_sas_token]
+ :language: python
+ :dedent: 8
+ :caption: Generating a shared access signature.
+ """
+ sas = SharedAccessSignature(account_name, account_key)
+ return sas.generate_account(
+ services=Services(blob=True),
+ resource_types=resource_types,
+ permission=permission,
+ expiry=expiry,
+ start=start,
+ ip=ip,
+ **kwargs
+ ) # type: ignore
+
+
+def generate_container_sas(
+ account_name, # type: str
+ container_name, # type: str
+ account_key=None, # type: Optional[str]
+ user_delegation_key=None, # type: Optional[UserDelegationKey]
+ permission=None, # type: Optional[Union[ContainerSasPermissions, str]]
+ expiry=None, # type: Optional[Union[datetime, str]]
+ start=None, # type: Optional[Union[datetime, str]]
+ policy_id=None, # type: Optional[str]
+ ip=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> Any
+ """Generates a shared access signature for a container.
+
+ Use the returned signature with the credential parameter of any BlobServiceClient,
+ ContainerClient or BlobClient.
+
+ :param str account_name:
+ The storage account name used to generate the shared access signature.
+ :param str container_name:
+ The name of the container.
+ :param str account_key:
+ The account key, also called shared key or access key, to generate the shared access signature.
+ Either `account_key` or `user_delegation_key` must be specified.
+ :param ~azure.storage.blob.UserDelegationKey user_delegation_key:
+ Instead of an account shared key, the user could pass in a user delegation key.
+ A user delegation key can be obtained from the service by authenticating with an AAD identity;
+ this can be accomplished by calling :func:`~azure.storage.blob.BlobServiceClient.get_user_delegation_key`.
+ When present, the SAS is signed with the user delegation key instead.
+ :param permission:
+ The permissions associated with the shared access signature. The
+ user is restricted to operations allowed by the permissions.
+ Permissions must be ordered racwdxyltfmei.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has been
+ specified in an associated stored access policy.
+ :type permission: str or ~azure.storage.blob.ContainerSasPermissions
+ :param expiry:
+ The time at which the shared access signature becomes invalid.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has
+ been specified in an associated stored access policy. Azure will always
+ convert values to UTC. If a date is passed in without timezone info, it
+ is assumed to be UTC.
+ :type expiry: ~datetime.datetime or str
+ :param start:
+ The time at which the shared access signature becomes valid. If
+ omitted, start time for this call is assumed to be the time when the
+ storage service receives the request. Azure will always convert values
+ to UTC. If a date is passed in without timezone info, it is assumed to
+ be UTC.
+ :type start: ~datetime.datetime or str
+ :param str policy_id:
+ A unique value up to 64 characters in length that correlates to a
+ stored access policy. To create a stored access policy, use
+ :func:`~azure.storage.blob.ContainerClient.set_container_access_policy`.
+ :param str ip:
+ Specifies an IP address or a range of IP addresses from which to accept requests.
+ If the IP address from which the request originates does not match the IP address
+ or address range specified on the SAS token, the request is not authenticated.
+ For example, specifying ip=168.1.5.65 or ip=168.1.5.60-168.1.5.70 on the SAS
+ restricts the request to those IP addresses.
+ :keyword str protocol:
+ Specifies the protocol permitted for a request made. The default value is https.
+ :keyword str cache_control:
+ Response header value for Cache-Control when resource is accessed
+ using this shared access signature.
+ :keyword str content_disposition:
+ Response header value for Content-Disposition when resource is accessed
+ using this shared access signature.
+ :keyword str content_encoding:
+ Response header value for Content-Encoding when resource is accessed
+ using this shared access signature.
+ :keyword str content_language:
+ Response header value for Content-Language when resource is accessed
+ using this shared access signature.
+ :keyword str content_type:
+ Response header value for Content-Type when resource is accessed
+ using this shared access signature.
+ :keyword str encryption_scope:
+ Specifies the encryption scope for a request made so that all write operations will be service encrypted.
+ :return: A Shared Access Signature (sas) token.
+ :rtype: str
+
+ .. admonition:: Example:
+
+ .. literalinclude:: ../samples/blob_samples_containers.py
+ :start-after: [START generate_sas_token]
+ :end-before: [END generate_sas_token]
+ :language: python
+ :dedent: 12
+ :caption: Generating a sas token.
+ """
+ if not user_delegation_key and not account_key:
+ raise ValueError("Either user_delegation_key or account_key must be provided.")
+ if isinstance(account_key, UserDelegationKey):
+ user_delegation_key = account_key
+ if user_delegation_key:
+ sas = BlobSharedAccessSignature(account_name, user_delegation_key=user_delegation_key)
+ else:
+ sas = BlobSharedAccessSignature(account_name, account_key=account_key)
+ return sas.generate_container(
+ container_name,
+ permission=permission,
+ expiry=expiry,
+ start=start,
+ policy_id=policy_id,
+ ip=ip,
+ **kwargs
+ )
+
+
+def generate_blob_sas(
+ account_name, # type: str
+ container_name, # type: str
+ blob_name, # type: str
+ snapshot=None, # type: Optional[str]
+ account_key=None, # type: Optional[str]
+ user_delegation_key=None, # type: Optional[UserDelegationKey]
+ permission=None, # type: Optional[Union[BlobSasPermissions, str]]
+ expiry=None, # type: Optional[Union[datetime, str]]
+ start=None, # type: Optional[Union[datetime, str]]
+ policy_id=None, # type: Optional[str]
+ ip=None, # type: Optional[str]
+ **kwargs # type: Any
+ ):
+ # type: (...) -> Any
+ """Generates a shared access signature for a blob.
+
+ Use the returned signature with the credential parameter of any BlobServiceClient,
+ ContainerClient or BlobClient.
+
+ :param str account_name:
+ The storage account name used to generate the shared access signature.
+ :param str container_name:
+ The name of the container.
+ :param str blob_name:
+ The name of the blob.
+ :param str snapshot:
+ An optional blob snapshot ID.
+ :param str account_key:
+ The account key, also called shared key or access key, to generate the shared access signature.
+ Either `account_key` or `user_delegation_key` must be specified.
+ :param ~azure.storage.blob.UserDelegationKey user_delegation_key:
+ Instead of an account shared key, the user could pass in a user delegation key.
+ A user delegation key can be obtained from the service by authenticating with an AAD identity;
+ this can be accomplished by calling :func:`~azure.storage.blob.BlobServiceClient.get_user_delegation_key`.
+ When present, the SAS is signed with the user delegation key instead.
+ :param permission:
+ The permissions associated with the shared access signature. The
+ user is restricted to operations allowed by the permissions.
+ Permissions must be ordered racwdxytmei.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has been
+ specified in an associated stored access policy.
+ :type permission: str or ~azure.storage.blob.BlobSasPermissions
+ :param expiry:
+ The time at which the shared access signature becomes invalid.
+ Required unless an id is given referencing a stored access policy
+ which contains this field. This field must be omitted if it has
+ been specified in an associated stored access policy. Azure will always
+ convert values to UTC. If a date is passed in without timezone info, it
+ is assumed to be UTC.
+ :type expiry: ~datetime.datetime or str
+ :param start:
+ The time at which the shared access signature becomes valid. If
+ omitted, start time for this call is assumed to be the time when the
+ storage service receives the request. Azure will always convert values
+ to UTC. If a date is passed in without timezone info, it is assumed to
+ be UTC.
+ :type start: ~datetime.datetime or str
+ :param str policy_id:
+ A unique value up to 64 characters in length that correlates to a
+ stored access policy. To create a stored access policy, use
+ :func:`~azure.storage.blob.ContainerClient.set_container_access_policy()`.
+ :param str ip:
+ Specifies an IP address or a range of IP addresses from which to accept requests.
+ If the IP address from which the request originates does not match the IP address
+ or address range specified on the SAS token, the request is not authenticated.
+ For example, specifying ip=168.1.5.65 or ip=168.1.5.60-168.1.5.70 on the SAS
+ restricts the request to those IP addresses.
+ :keyword str version_id:
+ An optional blob version ID. This parameter is only for versioning enabled account
+
+ .. versionadded:: 12.4.0
+ This keyword argument was introduced in API version '2019-12-12'.
+ :keyword str protocol:
+ Specifies the protocol permitted for a request made. The default value is https.
+ :keyword str cache_control:
+ Response header value for Cache-Control when resource is accessed
+ using this shared access signature.
+ :keyword str content_disposition:
+ Response header value for Content-Disposition when resource is accessed
+ using this shared access signature.
+ :keyword str content_encoding:
+ Response header value for Content-Encoding when resource is accessed
+ using this shared access signature.
+ :keyword str content_language:
+ Response header value for Content-Language when resource is accessed
+ using this shared access signature.
+ :keyword str content_type:
+ Response header value for Content-Type when resource is accessed
+ using this shared access signature.
+ :keyword str encryption_scope:
+ Specifies the encryption scope for a request made so that all write operations will be service encrypted.
+ :return: A Shared Access Signature (sas) token.
+ :rtype: str
+ """
+ if not user_delegation_key and not account_key:
+ raise ValueError("Either user_delegation_key or account_key must be provided.")
+ if isinstance(account_key, UserDelegationKey):
+ user_delegation_key = account_key
+ version_id = kwargs.pop('version_id', None)
+ if version_id and snapshot:
+ raise ValueError("snapshot and version_id cannot be set at the same time.")
+ if user_delegation_key:
+ sas = BlobSharedAccessSignature(account_name, user_delegation_key=user_delegation_key)
+ else:
+ sas = BlobSharedAccessSignature(account_name, account_key=account_key)
+ return sas.generate_blob(
+ container_name,
+ blob_name,
+ snapshot=snapshot,
+ version_id=version_id,
+ permission=permission,
+ expiry=expiry,
+ start=start,
+ policy_id=policy_id,
+ ip=ip,
+ **kwargs
+ )
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_upload_helpers.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_upload_helpers.py
new file mode 100644
index 00000000000..30d5bfae926
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_upload_helpers.py
@@ -0,0 +1,306 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+# pylint: disable=no-self-use
+
+from io import SEEK_SET, UnsupportedOperation
+from typing import Optional, Union, Any, TypeVar, TYPE_CHECKING # pylint: disable=unused-import
+
+import six
+from azure.core.exceptions import ResourceExistsError, ResourceModifiedError, HttpResponseError
+
+from ._shared.response_handlers import (
+ process_storage_error,
+ return_response_headers)
+from ._shared.models import StorageErrorCode
+from ._shared.uploads import (
+ upload_data_chunks,
+ upload_substream_blocks,
+ BlockBlobChunkUploader,
+ PageBlobChunkUploader,
+ AppendBlobChunkUploader)
+from ._shared.encryption import generate_blob_encryption_data, encrypt_blob
+from ._generated.models import (
+ BlockLookupList,
+ AppendPositionAccessConditions,
+ ModifiedAccessConditions,
+)
+
+if TYPE_CHECKING:
+ from datetime import datetime # pylint: disable=unused-import
+ BlobLeaseClient = TypeVar("BlobLeaseClient")
+
+_LARGE_BLOB_UPLOAD_MAX_READ_BUFFER_SIZE = 4 * 1024 * 1024
+_ERROR_VALUE_SHOULD_BE_SEEKABLE_STREAM = '{0} should be a seekable file-like/io.IOBase type stream object.'
+
+
+def _convert_mod_error(error):
+ message = error.message.replace(
+ "The condition specified using HTTP conditional header(s) is not met.",
+ "The specified blob already exists.")
+ message = message.replace("ConditionNotMet", "BlobAlreadyExists")
+ overwrite_error = ResourceExistsError(
+ message=message,
+ response=error.response,
+ error=error)
+ overwrite_error.error_code = StorageErrorCode.blob_already_exists
+ raise overwrite_error
+
+
+def _any_conditions(modified_access_conditions=None, **kwargs): # pylint: disable=unused-argument
+ return any([
+ modified_access_conditions.if_modified_since,
+ modified_access_conditions.if_unmodified_since,
+ modified_access_conditions.if_none_match,
+ modified_access_conditions.if_match
+ ])
+
+
+def upload_block_blob( # pylint: disable=too-many-locals
+ client=None,
+ data=None,
+ stream=None,
+ length=None,
+ overwrite=None,
+ headers=None,
+ validate_content=None,
+ max_concurrency=None,
+ blob_settings=None,
+ encryption_options=None,
+ **kwargs):
+ try:
+ if not overwrite and not _any_conditions(**kwargs):
+ kwargs['modified_access_conditions'].if_none_match = '*'
+ adjusted_count = length
+ if (encryption_options.get('key') is not None) and (adjusted_count is not None):
+ adjusted_count += (16 - (length % 16))
+ blob_headers = kwargs.pop('blob_headers', None)
+ tier = kwargs.pop('standard_blob_tier', None)
+ blob_tags_string = kwargs.pop('blob_tags_string', None)
+
+ immutability_policy = kwargs.pop('immutability_policy', None)
+ immutability_policy_expiry = None if immutability_policy is None else immutability_policy.expiry_time
+ immutability_policy_mode = None if immutability_policy is None else immutability_policy.policy_mode
+ legal_hold = kwargs.pop('legal_hold', None)
+
+ # Do single put if the size is smaller than or equal config.max_single_put_size
+ if adjusted_count is not None and (adjusted_count <= blob_settings.max_single_put_size):
+ try:
+ data = data.read(length)
+ if not isinstance(data, six.binary_type):
+ raise TypeError('Blob data should be of type bytes.')
+ except AttributeError:
+ pass
+ if encryption_options.get('key'):
+ encryption_data, data = encrypt_blob(data, encryption_options['key'])
+ headers['x-ms-meta-encryptiondata'] = encryption_data
+ return client.upload(
+ body=data,
+ content_length=adjusted_count,
+ blob_http_headers=blob_headers,
+ headers=headers,
+ cls=return_response_headers,
+ validate_content=validate_content,
+ data_stream_total=adjusted_count,
+ upload_stream_current=0,
+ tier=tier.value if tier else None,
+ blob_tags_string=blob_tags_string,
+ immutability_policy_expiry=immutability_policy_expiry,
+ immutability_policy_mode=immutability_policy_mode,
+ legal_hold=legal_hold,
+ **kwargs)
+
+ use_original_upload_path = blob_settings.use_byte_buffer or \
+ validate_content or encryption_options.get('required') or \
+ blob_settings.max_block_size < blob_settings.min_large_block_upload_threshold or \
+ hasattr(stream, 'seekable') and not stream.seekable() or \
+ not hasattr(stream, 'seek') or not hasattr(stream, 'tell')
+
+ if use_original_upload_path:
+ if encryption_options.get('key'):
+ cek, iv, encryption_data = generate_blob_encryption_data(encryption_options['key'])
+ headers['x-ms-meta-encryptiondata'] = encryption_data
+ encryption_options['cek'] = cek
+ encryption_options['vector'] = iv
+ block_ids = upload_data_chunks(
+ service=client,
+ uploader_class=BlockBlobChunkUploader,
+ total_size=length,
+ chunk_size=blob_settings.max_block_size,
+ max_concurrency=max_concurrency,
+ stream=stream,
+ validate_content=validate_content,
+ encryption_options=encryption_options,
+ headers=headers,
+ **kwargs
+ )
+ else:
+ block_ids = upload_substream_blocks(
+ service=client,
+ uploader_class=BlockBlobChunkUploader,
+ total_size=length,
+ chunk_size=blob_settings.max_block_size,
+ max_concurrency=max_concurrency,
+ stream=stream,
+ validate_content=validate_content,
+ headers=headers,
+ **kwargs
+ )
+
+ block_lookup = BlockLookupList(committed=[], uncommitted=[], latest=[])
+ block_lookup.latest = block_ids
+ return client.commit_block_list(
+ block_lookup,
+ blob_http_headers=blob_headers,
+ cls=return_response_headers,
+ validate_content=validate_content,
+ headers=headers,
+ tier=tier.value if tier else None,
+ blob_tags_string=blob_tags_string,
+ immutability_policy_expiry=immutability_policy_expiry,
+ immutability_policy_mode=immutability_policy_mode,
+ legal_hold=legal_hold,
+ **kwargs)
+ except HttpResponseError as error:
+ try:
+ process_storage_error(error)
+ except ResourceModifiedError as mod_error:
+ if not overwrite:
+ _convert_mod_error(mod_error)
+ raise
+
+
+def upload_page_blob(
+ client=None,
+ stream=None,
+ length=None,
+ overwrite=None,
+ headers=None,
+ validate_content=None,
+ max_concurrency=None,
+ blob_settings=None,
+ encryption_options=None,
+ **kwargs):
+ try:
+ if not overwrite and not _any_conditions(**kwargs):
+ kwargs['modified_access_conditions'].if_none_match = '*'
+ if length is None or length < 0:
+ raise ValueError("A content length must be specified for a Page Blob.")
+ if length % 512 != 0:
+ raise ValueError("Invalid page blob size: {0}. "
+ "The size must be aligned to a 512-byte boundary.".format(length))
+ if kwargs.get('premium_page_blob_tier'):
+ premium_page_blob_tier = kwargs.pop('premium_page_blob_tier')
+ try:
+ headers['x-ms-access-tier'] = premium_page_blob_tier.value
+ except AttributeError:
+ headers['x-ms-access-tier'] = premium_page_blob_tier
+ if encryption_options and encryption_options.get('data'):
+ headers['x-ms-meta-encryptiondata'] = encryption_options['data']
+ blob_tags_string = kwargs.pop('blob_tags_string', None)
+
+ response = client.create(
+ content_length=0,
+ blob_content_length=length,
+ blob_sequence_number=None,
+ blob_http_headers=kwargs.pop('blob_headers', None),
+ blob_tags_string=blob_tags_string,
+ cls=return_response_headers,
+ headers=headers,
+ **kwargs)
+ if length == 0:
+ return response
+
+ kwargs['modified_access_conditions'] = ModifiedAccessConditions(if_match=response['etag'])
+ return upload_data_chunks(
+ service=client,
+ uploader_class=PageBlobChunkUploader,
+ total_size=length,
+ chunk_size=blob_settings.max_page_size,
+ stream=stream,
+ max_concurrency=max_concurrency,
+ validate_content=validate_content,
+ encryption_options=encryption_options,
+ headers=headers,
+ **kwargs)
+
+ except HttpResponseError as error:
+ try:
+ process_storage_error(error)
+ except ResourceModifiedError as mod_error:
+ if not overwrite:
+ _convert_mod_error(mod_error)
+ raise
+
+
+def upload_append_blob( # pylint: disable=unused-argument
+ client=None,
+ stream=None,
+ length=None,
+ overwrite=None,
+ headers=None,
+ validate_content=None,
+ max_concurrency=None,
+ blob_settings=None,
+ encryption_options=None,
+ **kwargs):
+ try:
+ if length == 0:
+ return {}
+ blob_headers = kwargs.pop('blob_headers', None)
+ append_conditions = AppendPositionAccessConditions(
+ max_size=kwargs.pop('maxsize_condition', None),
+ append_position=None)
+ blob_tags_string = kwargs.pop('blob_tags_string', None)
+
+ try:
+ if overwrite:
+ client.create(
+ content_length=0,
+ blob_http_headers=blob_headers,
+ headers=headers,
+ blob_tags_string=blob_tags_string,
+ **kwargs)
+ return upload_data_chunks(
+ service=client,
+ uploader_class=AppendBlobChunkUploader,
+ total_size=length,
+ chunk_size=blob_settings.max_block_size,
+ stream=stream,
+ max_concurrency=max_concurrency,
+ validate_content=validate_content,
+ append_position_access_conditions=append_conditions,
+ headers=headers,
+ **kwargs)
+ except HttpResponseError as error:
+ if error.response.status_code != 404:
+ raise
+ # rewind the request body if it is a stream
+ if hasattr(stream, 'read'):
+ try:
+ # attempt to rewind the body to the initial position
+ stream.seek(0, SEEK_SET)
+ except UnsupportedOperation:
+ # if body is not seekable, then retry would not work
+ raise error
+ client.create(
+ content_length=0,
+ blob_http_headers=blob_headers,
+ headers=headers,
+ blob_tags_string=blob_tags_string,
+ **kwargs)
+ return upload_data_chunks(
+ service=client,
+ uploader_class=AppendBlobChunkUploader,
+ total_size=length,
+ chunk_size=blob_settings.max_block_size,
+ stream=stream,
+ max_concurrency=max_concurrency,
+ validate_content=validate_content,
+ append_position_access_conditions=append_conditions,
+ headers=headers,
+ **kwargs)
+ except HttpResponseError as error:
+ process_storage_error(error)
diff --git a/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_version.py b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_version.py
new file mode 100644
index 00000000000..b08ef47e08d
--- /dev/null
+++ b/src/storage-blob-preview/azext_storage_blob_preview/vendored_sdks/azure_storage_blob/v2021_04_10/_version.py
@@ -0,0 +1,7 @@
+# -------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+# --------------------------------------------------------------------------
+
+VERSION = "12.11.0"
diff --git a/src/storage-blob-preview/setup.py b/src/storage-blob-preview/setup.py
index 13a3f73765b..3caf7696e67 100644
--- a/src/storage-blob-preview/setup.py
+++ b/src/storage-blob-preview/setup.py
@@ -16,7 +16,7 @@
# TODO: Confirm this is the right version number you want and it matches your
# HISTORY.rst entry.
-VERSION = '0.6.1'
+VERSION = '0.6.2'
# The full list of classifiers is available at
# https://pypi.python.org/pypi?%3Aaction=list_classifiers