azure-storage-blob 12.21.0__py3-none-any.whl → 12.22.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- azure/storage/blob/__init__.py +19 -18
- azure/storage/blob/_blob_client.py +417 -1507
- azure/storage/blob/_blob_client_helpers.py +1242 -0
- azure/storage/blob/_blob_service_client.py +82 -101
- azure/storage/blob/_blob_service_client_helpers.py +27 -0
- azure/storage/blob/_container_client.py +147 -356
- azure/storage/blob/_container_client_helpers.py +261 -0
- azure/storage/blob/_deserialize.py +68 -44
- azure/storage/blob/_download.py +114 -90
- azure/storage/blob/_encryption.py +14 -7
- azure/storage/blob/_lease.py +47 -58
- azure/storage/blob/_list_blobs_helper.py +129 -135
- azure/storage/blob/_models.py +479 -276
- azure/storage/blob/_quick_query_helper.py +30 -31
- azure/storage/blob/_serialize.py +38 -56
- azure/storage/blob/_shared/avro/datafile.py +1 -1
- azure/storage/blob/_shared/avro/datafile_async.py +1 -1
- azure/storage/blob/_shared/base_client.py +1 -1
- azure/storage/blob/_shared/base_client_async.py +1 -1
- azure/storage/blob/_shared/policies.py +8 -6
- azure/storage/blob/_shared/policies_async.py +3 -1
- azure/storage/blob/_shared/response_handlers.py +6 -2
- azure/storage/blob/_shared/shared_access_signature.py +2 -2
- azure/storage/blob/_shared/uploads.py +1 -1
- azure/storage/blob/_shared/uploads_async.py +1 -1
- azure/storage/blob/_shared_access_signature.py +70 -53
- azure/storage/blob/_upload_helpers.py +75 -68
- azure/storage/blob/_version.py +1 -1
- azure/storage/blob/aio/__init__.py +19 -11
- azure/storage/blob/aio/_blob_client_async.py +505 -255
- azure/storage/blob/aio/_blob_service_client_async.py +138 -87
- azure/storage/blob/aio/_container_client_async.py +260 -120
- azure/storage/blob/aio/_download_async.py +104 -87
- azure/storage/blob/aio/_lease_async.py +56 -55
- azure/storage/blob/aio/_list_blobs_helper.py +94 -96
- azure/storage/blob/aio/_models.py +60 -38
- azure/storage/blob/aio/_upload_helpers.py +75 -66
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/METADATA +1 -1
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/RECORD +42 -39
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/LICENSE +0 -0
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/WHEEL +0 -0
- {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/top_level.txt +0 -0
@@ -6,11 +6,13 @@
|
|
6
6
|
# pylint: disable=too-many-lines, invalid-overridden-method, docstring-keyword-should-match-keyword-only
|
7
7
|
|
8
8
|
import warnings
|
9
|
+
from datetime import datetime
|
9
10
|
from functools import partial
|
10
|
-
from typing import (
|
11
|
-
Any, AnyStr, AsyncIterable, Dict, IO, Iterable, List, Optional, overload, Tuple, Union,
|
11
|
+
from typing import (
|
12
|
+
Any, AnyStr, AsyncIterable, cast, Dict, IO, Iterable, List, Optional, overload, Tuple, Union,
|
12
13
|
TYPE_CHECKING
|
13
14
|
)
|
15
|
+
from typing_extensions import Self
|
14
16
|
|
15
17
|
from azure.core.async_paging import AsyncItemPaged
|
16
18
|
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError, ResourceExistsError
|
@@ -18,44 +20,76 @@ from azure.core.pipeline import AsyncPipeline
|
|
18
20
|
from azure.core.tracing.decorator import distributed_trace
|
19
21
|
from azure.core.tracing.decorator_async import distributed_trace_async
|
20
22
|
|
21
|
-
from .._shared.base_client_async import AsyncStorageAccountHostsMixin, AsyncTransportWrapper
|
22
|
-
from .._shared.policies_async import ExponentialRetry
|
23
|
-
from .._shared.response_handlers import return_response_headers, process_storage_error
|
24
|
-
from .._generated.aio import AzureBlobStorage
|
25
|
-
from .._generated.models import CpkInfo
|
26
|
-
from .._blob_client import BlobClient as BlobClientBase
|
27
|
-
from .._deserialize import (
|
28
|
-
deserialize_blob_properties,
|
29
|
-
deserialize_pipeline_response_into_cls,
|
30
|
-
get_page_ranges_result,
|
31
|
-
parse_tags
|
32
|
-
)
|
33
|
-
from .._encryption import StorageEncryptionMixin
|
34
|
-
from .._models import BlobType, BlobBlock, BlobProperties, PageRange
|
35
|
-
from .._serialize import get_modify_conditions, get_api_version, get_access_conditions, get_version_id
|
36
23
|
from ._download_async import StorageStreamDownloader
|
37
24
|
from ._lease_async import BlobLeaseClient
|
38
25
|
from ._models import PageRangePaged
|
39
26
|
from ._upload_helpers import (
|
40
|
-
upload_block_blob,
|
41
27
|
upload_append_blob,
|
28
|
+
upload_block_blob,
|
42
29
|
upload_page_blob
|
43
30
|
)
|
31
|
+
from .._blob_client import StorageAccountHostsMixin
|
32
|
+
from .._blob_client_helpers import (
|
33
|
+
_abort_copy_options,
|
34
|
+
_append_block_from_url_options,
|
35
|
+
_append_block_options,
|
36
|
+
_clear_page_options,
|
37
|
+
_commit_block_list_options,
|
38
|
+
_create_append_blob_options,
|
39
|
+
_create_page_blob_options,
|
40
|
+
_create_snapshot_options,
|
41
|
+
_delete_blob_options,
|
42
|
+
_download_blob_options,
|
43
|
+
_format_url,
|
44
|
+
_from_blob_url,
|
45
|
+
_get_blob_tags_options,
|
46
|
+
_get_block_list_result,
|
47
|
+
_get_page_ranges_options,
|
48
|
+
_parse_url,
|
49
|
+
_resize_blob_options,
|
50
|
+
_seal_append_blob_options,
|
51
|
+
_set_blob_metadata_options,
|
52
|
+
_set_blob_tags_options,
|
53
|
+
_set_http_headers_options,
|
54
|
+
_set_sequence_number_options,
|
55
|
+
_stage_block_from_url_options,
|
56
|
+
_stage_block_options,
|
57
|
+
_start_copy_from_url_options,
|
58
|
+
_upload_blob_from_url_options,
|
59
|
+
_upload_blob_options,
|
60
|
+
_upload_page_options,
|
61
|
+
_upload_pages_from_url_options
|
62
|
+
)
|
63
|
+
from .._deserialize import (
|
64
|
+
deserialize_blob_properties,
|
65
|
+
deserialize_pipeline_response_into_cls,
|
66
|
+
get_page_ranges_result,
|
67
|
+
parse_tags
|
68
|
+
)
|
69
|
+
from .._encryption import StorageEncryptionMixin, _ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION
|
70
|
+
from .._generated.aio import AzureBlobStorage
|
71
|
+
from .._generated.models import CpkInfo
|
72
|
+
from .._models import BlobType, BlobBlock, BlobProperties, PageRange
|
73
|
+
from .._serialize import get_access_conditions, get_api_version, get_modify_conditions, get_version_id
|
74
|
+
from .._shared.base_client_async import AsyncStorageAccountHostsMixin, AsyncTransportWrapper, parse_connection_str
|
75
|
+
from .._shared.policies_async import ExponentialRetry
|
76
|
+
from .._shared.response_handlers import process_storage_error, return_response_headers
|
44
77
|
|
45
78
|
if TYPE_CHECKING:
|
46
79
|
from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential
|
47
80
|
from azure.core.credentials_async import AsyncTokenCredential
|
48
|
-
from
|
49
|
-
from
|
81
|
+
from azure.core.pipeline.policies import AsyncHTTPPolicy
|
82
|
+
from azure.storage.blob.aio import ContainerClient
|
83
|
+
from .._models import (
|
50
84
|
ContentSettings,
|
51
85
|
ImmutabilityPolicy,
|
52
86
|
PremiumPageBlobTier,
|
53
|
-
|
54
|
-
|
87
|
+
SequenceNumberAction,
|
88
|
+
StandardBlobTier
|
55
89
|
)
|
56
90
|
|
57
91
|
|
58
|
-
class BlobClient(AsyncStorageAccountHostsMixin,
|
92
|
+
class BlobClient(AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin): # type: ignore [misc] # pylint: disable=too-many-public-methods
|
59
93
|
"""A client to interact with a specific blob, although that blob may not yet exist.
|
60
94
|
|
61
95
|
:param str account_url:
|
@@ -128,22 +162,139 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
128
162
|
snapshot: Optional[Union[str, Dict[str, Any]]] = None,
|
129
163
|
credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long
|
130
164
|
**kwargs: Any
|
131
|
-
|
165
|
+
) -> None:
|
132
166
|
kwargs['retry_policy'] = kwargs.get('retry_policy') or ExponentialRetry(**kwargs)
|
133
|
-
|
134
|
-
account_url,
|
167
|
+
parsed_url, sas_token, path_snapshot = _parse_url(
|
168
|
+
account_url=account_url,
|
135
169
|
container_name=container_name,
|
136
|
-
blob_name=blob_name
|
137
|
-
|
138
|
-
|
139
|
-
|
170
|
+
blob_name=blob_name)
|
171
|
+
self.container_name = container_name
|
172
|
+
self.blob_name = blob_name
|
173
|
+
|
174
|
+
if snapshot is not None and hasattr(snapshot, 'snapshot'):
|
175
|
+
self.snapshot = snapshot.snapshot
|
176
|
+
elif isinstance(snapshot, dict):
|
177
|
+
self.snapshot = snapshot['snapshot']
|
178
|
+
else:
|
179
|
+
self.snapshot = snapshot or path_snapshot
|
180
|
+
self.version_id = kwargs.pop('version_id', None)
|
181
|
+
|
182
|
+
# This parameter is used for the hierarchy traversal. Give precedence to credential.
|
183
|
+
self._raw_credential = credential if credential else sas_token
|
184
|
+
self._query_str, credential = self._format_query_string(sas_token, credential, snapshot=self.snapshot)
|
185
|
+
super(BlobClient, self).__init__(parsed_url, service='blob', credential=credential, **kwargs)
|
140
186
|
self._client = AzureBlobStorage(self.url, base_url=self.url, pipeline=self._pipeline)
|
141
|
-
self._client._config.version = get_api_version(kwargs) # pylint: disable=protected-access
|
187
|
+
self._client._config.version = get_api_version(kwargs) # type: ignore [assignment] # pylint: disable=protected-access
|
142
188
|
self._configure_encryption(kwargs)
|
143
189
|
|
190
|
+
def _format_url(self, hostname: str) -> str:
|
191
|
+
return _format_url(
|
192
|
+
container_name=self.container_name,
|
193
|
+
scheme=self.scheme,
|
194
|
+
blob_name=self.blob_name,
|
195
|
+
query_str=self._query_str,
|
196
|
+
hostname=hostname
|
197
|
+
)
|
198
|
+
|
199
|
+
@classmethod
|
200
|
+
def from_blob_url(
|
201
|
+
cls, blob_url: str,
|
202
|
+
credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long
|
203
|
+
snapshot: Optional[Union[str, Dict[str, Any]]] = None,
|
204
|
+
**kwargs: Any
|
205
|
+
) -> Self:
|
206
|
+
"""Create BlobClient from a blob url. This doesn't support customized blob url with '/' in blob name.
|
207
|
+
|
208
|
+
:param str blob_url:
|
209
|
+
The full endpoint URL to the Blob, including SAS token and snapshot if used. This could be
|
210
|
+
either the primary endpoint, or the secondary endpoint depending on the current `location_mode`.
|
211
|
+
:type blob_url: str
|
212
|
+
:param credential:
|
213
|
+
The credentials with which to authenticate. This is optional if the
|
214
|
+
account URL already has a SAS token, or the connection string already has shared
|
215
|
+
access key values. The value can be a SAS token string,
|
216
|
+
an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
|
217
|
+
an account shared access key, or an instance of a TokenCredentials class from azure.identity.
|
218
|
+
If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
|
219
|
+
- except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
|
220
|
+
If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
|
221
|
+
should be the storage account key.
|
222
|
+
:type credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] # pylint: disable=line-too-long
|
223
|
+
:param str snapshot:
|
224
|
+
The optional blob snapshot on which to operate. This can be the snapshot ID string
|
225
|
+
or the response returned from :func:`create_snapshot`. If specified, this will override
|
226
|
+
the snapshot in the url.
|
227
|
+
:keyword str version_id: The version id parameter is an opaque DateTime value that, when present,
|
228
|
+
specifies the version of the blob to operate on.
|
229
|
+
:keyword str audience: The audience to use when requesting tokens for Azure Active Directory
|
230
|
+
authentication. Only has an effect when credential is of type TokenCredential. The value could be
|
231
|
+
https://storage.azure.com/ (default) or https://<account>.blob.core.windows.net.
|
232
|
+
:returns: A Blob client.
|
233
|
+
:rtype: ~azure.storage.blob.BlobClient
|
234
|
+
"""
|
235
|
+
account_url, container_name, blob_name, path_snapshot = _from_blob_url(blob_url=blob_url, snapshot=snapshot)
|
236
|
+
return cls(
|
237
|
+
account_url, container_name=container_name, blob_name=blob_name,
|
238
|
+
snapshot=path_snapshot, credential=credential, **kwargs
|
239
|
+
)
|
240
|
+
|
241
|
+
@classmethod
|
242
|
+
def from_connection_string(
|
243
|
+
cls, conn_str: str,
|
244
|
+
container_name: str,
|
245
|
+
blob_name: str,
|
246
|
+
snapshot: Optional[Union[str, Dict[str, Any]]] = None,
|
247
|
+
credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long
|
248
|
+
**kwargs: Any
|
249
|
+
) -> Self:
|
250
|
+
"""Create BlobClient from a Connection String.
|
251
|
+
|
252
|
+
:param str conn_str:
|
253
|
+
A connection string to an Azure Storage account.
|
254
|
+
:param container_name: The container name for the blob.
|
255
|
+
:type container_name: str
|
256
|
+
:param blob_name: The name of the blob with which to interact.
|
257
|
+
:type blob_name: str
|
258
|
+
:param str snapshot:
|
259
|
+
The optional blob snapshot on which to operate. This can be the snapshot ID string
|
260
|
+
or the response returned from :func:`create_snapshot`.
|
261
|
+
:param credential:
|
262
|
+
The credentials with which to authenticate. This is optional if the
|
263
|
+
account URL already has a SAS token, or the connection string already has shared
|
264
|
+
access key values. The value can be a SAS token string,
|
265
|
+
an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
|
266
|
+
an account shared access key, or an instance of a TokenCredentials class from azure.identity.
|
267
|
+
Credentials provided here will take precedence over those in the connection string.
|
268
|
+
If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
|
269
|
+
should be the storage account key.
|
270
|
+
:type credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] # pylint: disable=line-too-long
|
271
|
+
:keyword str version_id: The version id parameter is an opaque DateTime value that, when present,
|
272
|
+
specifies the version of the blob to operate on.
|
273
|
+
:keyword str audience: The audience to use when requesting tokens for Azure Active Directory
|
274
|
+
authentication. Only has an effect when credential is of type TokenCredential. The value could be
|
275
|
+
https://storage.azure.com/ (default) or https://<account>.blob.core.windows.net.
|
276
|
+
:returns: A Blob client.
|
277
|
+
:rtype: ~azure.storage.blob.BlobClient
|
278
|
+
|
279
|
+
.. admonition:: Example:
|
280
|
+
|
281
|
+
.. literalinclude:: ../samples/blob_samples_authentication.py
|
282
|
+
:start-after: [START auth_from_connection_string_blob]
|
283
|
+
:end-before: [END auth_from_connection_string_blob]
|
284
|
+
:language: python
|
285
|
+
:dedent: 8
|
286
|
+
:caption: Creating the BlobClient from a connection string.
|
287
|
+
"""
|
288
|
+
account_url, secondary, credential = parse_connection_str(conn_str, credential, 'blob')
|
289
|
+
if 'secondary_hostname' not in kwargs:
|
290
|
+
kwargs['secondary_hostname'] = secondary
|
291
|
+
return cls(
|
292
|
+
account_url, container_name=container_name, blob_name=blob_name,
|
293
|
+
snapshot=snapshot, credential=credential, **kwargs
|
294
|
+
)
|
295
|
+
|
144
296
|
@distributed_trace_async
|
145
|
-
async def get_account_information(self, **kwargs
|
146
|
-
# type: (Optional[int]) -> Dict[str, str]
|
297
|
+
async def get_account_information(self, **kwargs: Any) -> Dict[str, str]:
|
147
298
|
"""Gets information related to the storage account in which the blob resides.
|
148
299
|
|
149
300
|
The information can also be retrieved if the user has a SAS to a container or blob.
|
@@ -153,13 +304,13 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
153
304
|
:rtype: dict(str, str)
|
154
305
|
"""
|
155
306
|
try:
|
156
|
-
return
|
307
|
+
return cast(Dict[str, str],
|
308
|
+
await self._client.blob.get_account_info(cls=return_response_headers, **kwargs))
|
157
309
|
except HttpResponseError as error:
|
158
310
|
process_storage_error(error)
|
159
311
|
|
160
312
|
@distributed_trace_async
|
161
|
-
async def upload_blob_from_url(self, source_url, **kwargs):
|
162
|
-
# type: (str, Any) -> Dict[str, Any]
|
313
|
+
async def upload_blob_from_url(self, source_url: str, **kwargs: Any) -> Dict[str, Any]:
|
163
314
|
"""
|
164
315
|
Creates a new Block Blob where the content of the blob is read from a given URL.
|
165
316
|
The content of an existing blob is overwritten with the new blob.
|
@@ -257,25 +408,28 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
257
408
|
:returns: Response from creating a new block blob for a given URL.
|
258
409
|
:rtype: Dict[str, Any]
|
259
410
|
"""
|
260
|
-
|
261
|
-
|
411
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
412
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
413
|
+
options = _upload_blob_from_url_options(
|
414
|
+
source_url=source_url,
|
262
415
|
**kwargs)
|
263
416
|
try:
|
264
|
-
return await self._client.block_blob.put_blob_from_url(**options)
|
417
|
+
return cast(Dict[str, Any], await self._client.block_blob.put_blob_from_url(**options))
|
265
418
|
except HttpResponseError as error:
|
266
419
|
process_storage_error(error)
|
267
420
|
|
268
421
|
@distributed_trace_async
|
269
422
|
async def upload_blob(
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
423
|
+
self, data: Union[bytes, str, Iterable[AnyStr], AsyncIterable[AnyStr], IO[bytes]],
|
424
|
+
blob_type: Union[str, BlobType] = BlobType.BLOCKBLOB,
|
425
|
+
length: Optional[int] = None,
|
426
|
+
metadata: Optional[Dict[str, str]] = None,
|
427
|
+
**kwargs: Any
|
428
|
+
) -> Dict[str, Any]:
|
276
429
|
"""Creates a new blob from a data source with automatic chunking.
|
277
430
|
|
278
431
|
:param data: The blob data to upload.
|
432
|
+
:type data: Union[bytes, str, Iterable[AnyStr], AsyncIterable[AnyStr], IO[AnyStr]]
|
279
433
|
:param ~azure.storage.blob.BlobType blob_type: The type of the blob. This can be
|
280
434
|
either BlockBlob, PageBlob or AppendBlob. The default value is BlockBlob.
|
281
435
|
:param int length:
|
@@ -411,43 +565,59 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
411
565
|
:dedent: 16
|
412
566
|
:caption: Upload a blob to the container.
|
413
567
|
"""
|
414
|
-
|
415
|
-
|
568
|
+
if self.require_encryption and not self.key_encryption_key:
|
569
|
+
raise ValueError("Encryption required but no key was provided.")
|
570
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
571
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
572
|
+
options = _upload_blob_options(
|
573
|
+
data=data,
|
416
574
|
blob_type=blob_type,
|
417
575
|
length=length,
|
418
576
|
metadata=metadata,
|
577
|
+
encryption_options={
|
578
|
+
'required': self.require_encryption,
|
579
|
+
'version': self.encryption_version,
|
580
|
+
'key': self.key_encryption_key,
|
581
|
+
'resolver': self.key_resolver_function
|
582
|
+
},
|
583
|
+
config=self._config,
|
584
|
+
sdk_moniker=self._sdk_moniker,
|
585
|
+
client=self._client,
|
419
586
|
**kwargs)
|
420
587
|
if blob_type == BlobType.BlockBlob:
|
421
|
-
return await upload_block_blob(**options)
|
588
|
+
return cast(Dict[str, Any], await upload_block_blob(**options))
|
422
589
|
if blob_type == BlobType.PageBlob:
|
423
|
-
return await upload_page_blob(**options)
|
424
|
-
return await upload_append_blob(**options)
|
590
|
+
return cast(Dict[str, Any], await upload_page_blob(**options))
|
591
|
+
return cast(Dict[str, Any], await upload_append_blob(**options))
|
425
592
|
|
426
593
|
@overload
|
427
594
|
async def download_blob(
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
595
|
+
self, offset: Optional[int] = None,
|
596
|
+
length: Optional[int] = None,
|
597
|
+
*,
|
598
|
+
encoding: str,
|
599
|
+
**kwargs: Any
|
600
|
+
) -> StorageStreamDownloader[str]:
|
433
601
|
...
|
434
602
|
|
435
603
|
@overload
|
436
604
|
async def download_blob(
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
605
|
+
self, offset: Optional[int] = None,
|
606
|
+
length: Optional[int] = None,
|
607
|
+
*,
|
608
|
+
encoding: None = None,
|
609
|
+
**kwargs: Any
|
610
|
+
) -> StorageStreamDownloader[bytes]:
|
442
611
|
...
|
443
612
|
|
444
613
|
@distributed_trace_async
|
445
614
|
async def download_blob(
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
615
|
+
self, offset: Optional[int] = None,
|
616
|
+
length: Optional[int] = None,
|
617
|
+
*,
|
618
|
+
encoding: Union[str, None] = None,
|
619
|
+
**kwargs: Any
|
620
|
+
) -> Union[StorageStreamDownloader[str], StorageStreamDownloader[bytes]]:
|
451
621
|
"""Downloads a blob to the StorageStreamDownloader. The readall() method must
|
452
622
|
be used to read all the content or readinto() must be used to download the blob into
|
453
623
|
a stream. Using chunks() returns an async iterator which allows the user to iterate over the content in chunks.
|
@@ -538,18 +708,35 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
538
708
|
:dedent: 16
|
539
709
|
:caption: Download a blob.
|
540
710
|
"""
|
541
|
-
|
711
|
+
if self.require_encryption and not (self.key_encryption_key or self.key_resolver_function):
|
712
|
+
raise ValueError("Encryption required but no key was provided.")
|
713
|
+
if length is not None and offset is None:
|
714
|
+
raise ValueError("Offset value must not be None if length is set.")
|
715
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
716
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
717
|
+
options = _download_blob_options(
|
718
|
+
blob_name=self.blob_name,
|
719
|
+
container_name=self.container_name,
|
720
|
+
version_id=get_version_id(self.version_id, kwargs),
|
542
721
|
offset=offset,
|
543
722
|
length=length,
|
544
723
|
encoding=encoding,
|
724
|
+
encryption_options={
|
725
|
+
'required': self.require_encryption,
|
726
|
+
'version': self.encryption_version,
|
727
|
+
'key': self.key_encryption_key,
|
728
|
+
'resolver': self.key_resolver_function
|
729
|
+
},
|
730
|
+
config=self._config,
|
731
|
+
sdk_moniker=self._sdk_moniker,
|
732
|
+
client=self._client,
|
545
733
|
**kwargs)
|
546
734
|
downloader = StorageStreamDownloader(**options)
|
547
735
|
await downloader._setup() # pylint: disable=protected-access
|
548
736
|
return downloader
|
549
737
|
|
550
738
|
@distributed_trace_async
|
551
|
-
async def delete_blob(self, delete_snapshots=None, **kwargs):
|
552
|
-
# type: (str, Any) -> None
|
739
|
+
async def delete_blob(self, delete_snapshots: Optional[str] = None, **kwargs: Any) -> None:
|
553
740
|
"""Marks the specified blob for deletion.
|
554
741
|
|
555
742
|
The blob is later deleted during garbage collection.
|
@@ -620,15 +807,18 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
620
807
|
:dedent: 16
|
621
808
|
:caption: Delete a blob.
|
622
809
|
"""
|
623
|
-
options =
|
810
|
+
options = _delete_blob_options(
|
811
|
+
snapshot=self.snapshot,
|
812
|
+
version_id=get_version_id(self.version_id, kwargs),
|
813
|
+
delete_snapshots=delete_snapshots,
|
814
|
+
**kwargs)
|
624
815
|
try:
|
625
816
|
await self._client.blob.delete(**options)
|
626
817
|
except HttpResponseError as error:
|
627
818
|
process_storage_error(error)
|
628
819
|
|
629
820
|
@distributed_trace_async
|
630
|
-
async def undelete_blob(self, **kwargs):
|
631
|
-
# type: (Any) -> None
|
821
|
+
async def undelete_blob(self, **kwargs: Any) -> None:
|
632
822
|
"""Restores soft-deleted blobs or snapshots.
|
633
823
|
|
634
824
|
Operation will only be successful if used within the specified number of days
|
@@ -661,8 +851,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
661
851
|
process_storage_error(error)
|
662
852
|
|
663
853
|
@distributed_trace_async
|
664
|
-
async def exists(self, **kwargs):
|
665
|
-
# type: (**Any) -> bool
|
854
|
+
async def exists(self, **kwargs: Any) -> bool:
|
666
855
|
"""
|
667
856
|
Returns True if a blob exists with the defined parameters, and returns
|
668
857
|
False otherwise.
|
@@ -696,8 +885,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
696
885
|
return False
|
697
886
|
|
698
887
|
@distributed_trace_async
|
699
|
-
async def get_blob_properties(self, **kwargs):
|
700
|
-
# type: (Any) -> BlobProperties
|
888
|
+
async def get_blob_properties(self, **kwargs: Any) -> BlobProperties:
|
701
889
|
"""Returns all user-defined metadata, standard HTTP properties, and
|
702
890
|
system properties for the blob. It does not return the content of the blob.
|
703
891
|
|
@@ -788,11 +976,13 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
788
976
|
if isinstance(blob_props, BlobProperties):
|
789
977
|
blob_props.container = self.container_name
|
790
978
|
blob_props.snapshot = self.snapshot
|
791
|
-
return blob_props
|
979
|
+
return cast(BlobProperties, blob_props)
|
792
980
|
|
793
981
|
@distributed_trace_async
|
794
|
-
async def set_http_headers(
|
795
|
-
|
982
|
+
async def set_http_headers(
|
983
|
+
self, content_settings: Optional["ContentSettings"] = None,
|
984
|
+
**kwargs: Any
|
985
|
+
) -> Dict[str, Any]:
|
796
986
|
"""Sets system properties on the blob.
|
797
987
|
|
798
988
|
If one property is set for the content_settings, all properties will be overridden.
|
@@ -836,15 +1026,17 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
836
1026
|
:returns: Blob-updated property dict (Etag and last modified)
|
837
1027
|
:rtype: Dict[str, Any]
|
838
1028
|
"""
|
839
|
-
options =
|
1029
|
+
options = _set_http_headers_options(content_settings=content_settings, **kwargs)
|
840
1030
|
try:
|
841
|
-
return await self._client.blob.set_http_headers(**options)
|
1031
|
+
return cast(Dict[str, Any], await self._client.blob.set_http_headers(**options))
|
842
1032
|
except HttpResponseError as error:
|
843
1033
|
process_storage_error(error)
|
844
1034
|
|
845
1035
|
@distributed_trace_async
|
846
|
-
async def set_blob_metadata(
|
847
|
-
|
1036
|
+
async def set_blob_metadata(
|
1037
|
+
self, metadata: Optional[Dict[str, str]] = None,
|
1038
|
+
**kwargs: Any
|
1039
|
+
) -> Dict[str, Union[str, datetime]]:
|
848
1040
|
"""Sets user-defined metadata for the blob as one or more name-value pairs.
|
849
1041
|
|
850
1042
|
:param metadata:
|
@@ -901,15 +1093,19 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
901
1093
|
:returns: Blob-updated property dict (Etag and last modified)
|
902
1094
|
:rtype: Dict[str, Union[str, datetime]]
|
903
1095
|
"""
|
904
|
-
|
1096
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
1097
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
1098
|
+
options = _set_blob_metadata_options(metadata=metadata, **kwargs)
|
905
1099
|
try:
|
906
|
-
return await self._client.blob.set_metadata(**options)
|
1100
|
+
return cast(Dict[str, Union[str, datetime]], await self._client.blob.set_metadata(**options))
|
907
1101
|
except HttpResponseError as error:
|
908
1102
|
process_storage_error(error)
|
909
1103
|
|
910
1104
|
@distributed_trace_async
|
911
|
-
async def set_immutability_policy(
|
912
|
-
|
1105
|
+
async def set_immutability_policy(
|
1106
|
+
self, immutability_policy: "ImmutabilityPolicy",
|
1107
|
+
**kwargs: Any
|
1108
|
+
) -> Dict[str, str]:
|
913
1109
|
"""The Set Immutability Policy operation sets the immutability policy on the blob.
|
914
1110
|
|
915
1111
|
.. versionadded:: 12.10.0
|
@@ -933,11 +1129,11 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
933
1129
|
|
934
1130
|
kwargs['immutability_policy_expiry'] = immutability_policy.expiry_time
|
935
1131
|
kwargs['immutability_policy_mode'] = immutability_policy.policy_mode
|
936
|
-
return
|
1132
|
+
return cast(Dict[str, str],
|
1133
|
+
await self._client.blob.set_immutability_policy(cls=return_response_headers, **kwargs))
|
937
1134
|
|
938
1135
|
@distributed_trace_async
|
939
|
-
async def delete_immutability_policy(self, **kwargs):
|
940
|
-
# type: (**Any) -> None
|
1136
|
+
async def delete_immutability_policy(self, **kwargs: Any) -> None:
|
941
1137
|
"""The Delete Immutability Policy operation deletes the immutability policy on the blob.
|
942
1138
|
|
943
1139
|
.. versionadded:: 12.10.0
|
@@ -956,8 +1152,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
956
1152
|
await self._client.blob.delete_immutability_policy(**kwargs)
|
957
1153
|
|
958
1154
|
@distributed_trace_async
|
959
|
-
async def set_legal_hold(self, legal_hold, **kwargs):
|
960
|
-
# type: (bool, **Any) -> Dict[str, Union[str, datetime, bool]]
|
1155
|
+
async def set_legal_hold(self, legal_hold: bool, **kwargs: Any) -> Dict[str, Union[str, datetime, bool]]:
|
961
1156
|
"""The Set Legal Hold operation sets a legal hold on the blob.
|
962
1157
|
|
963
1158
|
.. versionadded:: 12.10.0
|
@@ -975,17 +1170,17 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
975
1170
|
:rtype: Dict[str, Union[str, datetime, bool]]
|
976
1171
|
"""
|
977
1172
|
|
978
|
-
return
|
1173
|
+
return cast(Dict[str, Union[str, datetime, bool]],
|
1174
|
+
await self._client.blob.set_legal_hold(legal_hold, cls=return_response_headers, **kwargs))
|
979
1175
|
|
980
1176
|
@distributed_trace_async
|
981
|
-
async def create_page_blob(
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
# type: (...) -> Dict[str, Union[str, datetime]]
|
1177
|
+
async def create_page_blob(
|
1178
|
+
self, size: int,
|
1179
|
+
content_settings: Optional["ContentSettings"] = None,
|
1180
|
+
metadata: Optional[Dict[str, str]] = None,
|
1181
|
+
premium_page_blob_tier: Optional[Union[str, "PremiumPageBlobTier"]] = None,
|
1182
|
+
**kwargs: Any
|
1183
|
+
) -> Dict[str, Union[str, datetime]]:
|
989
1184
|
"""Creates a new Page Blob of the specified size.
|
990
1185
|
|
991
1186
|
:param int size:
|
@@ -1070,20 +1265,27 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1070
1265
|
:returns: Blob-updated property dict (Etag and last modified).
|
1071
1266
|
:rtype: dict[str, Any]
|
1072
1267
|
"""
|
1073
|
-
|
1074
|
-
|
1268
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
1269
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
1270
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
1271
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
1272
|
+
options = _create_page_blob_options(
|
1273
|
+
size=size,
|
1075
1274
|
content_settings=content_settings,
|
1076
1275
|
metadata=metadata,
|
1077
1276
|
premium_page_blob_tier=premium_page_blob_tier,
|
1078
1277
|
**kwargs)
|
1079
1278
|
try:
|
1080
|
-
return await self._client.page_blob.create(**options)
|
1279
|
+
return cast(Dict[str, Any], await self._client.page_blob.create(**options))
|
1081
1280
|
except HttpResponseError as error:
|
1082
1281
|
process_storage_error(error)
|
1083
1282
|
|
1084
1283
|
@distributed_trace_async
|
1085
|
-
async def create_append_blob(
|
1086
|
-
|
1284
|
+
async def create_append_blob(
|
1285
|
+
self, content_settings: Optional["ContentSettings"] = None,
|
1286
|
+
metadata: Optional[Dict[str, str]] = None,
|
1287
|
+
**kwargs: Any
|
1288
|
+
) -> Dict[str, Union[str, datetime]]:
|
1087
1289
|
"""Creates a new Append Blob. This operation creates a new 0-length append blob. The content
|
1088
1290
|
of any existing blob is overwritten with the newly initialized append blob. To add content to
|
1089
1291
|
the append blob, call the :func:`append_block` or :func:`append_block_from_url` method.
|
@@ -1159,18 +1361,24 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1159
1361
|
:returns: Blob-updated property dict (Etag and last modified).
|
1160
1362
|
:rtype: dict[str, Any]
|
1161
1363
|
"""
|
1162
|
-
|
1364
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
1365
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
1366
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
1367
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
1368
|
+
options = _create_append_blob_options(
|
1163
1369
|
content_settings=content_settings,
|
1164
1370
|
metadata=metadata,
|
1165
1371
|
**kwargs)
|
1166
1372
|
try:
|
1167
|
-
return await self._client.append_blob.create(**options)
|
1373
|
+
return cast(Dict[str, Union[str, datetime]], await self._client.append_blob.create(**options))
|
1168
1374
|
except HttpResponseError as error:
|
1169
1375
|
process_storage_error(error)
|
1170
1376
|
|
1171
1377
|
@distributed_trace_async
|
1172
|
-
async def create_snapshot(
|
1173
|
-
|
1378
|
+
async def create_snapshot(
|
1379
|
+
self, metadata: Optional[Dict[str, str]] = None,
|
1380
|
+
**kwargs: Any
|
1381
|
+
) -> Dict[str, Union[str, datetime]]:
|
1174
1382
|
"""Creates a snapshot of the blob.
|
1175
1383
|
|
1176
1384
|
A snapshot is a read-only version of a blob that's taken at a point in time.
|
@@ -1242,15 +1450,21 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1242
1450
|
:dedent: 12
|
1243
1451
|
:caption: Create a snapshot of the blob.
|
1244
1452
|
"""
|
1245
|
-
|
1453
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
1454
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
1455
|
+
options = _create_snapshot_options(metadata=metadata, **kwargs)
|
1246
1456
|
try:
|
1247
|
-
return await self._client.blob.create_snapshot(**options)
|
1457
|
+
return cast(Dict[str, Any], await self._client.blob.create_snapshot(**options))
|
1248
1458
|
except HttpResponseError as error:
|
1249
1459
|
process_storage_error(error)
|
1250
1460
|
|
1251
1461
|
@distributed_trace_async
|
1252
|
-
async def start_copy_from_url(
|
1253
|
-
|
1462
|
+
async def start_copy_from_url(
|
1463
|
+
self, source_url: str,
|
1464
|
+
metadata: Optional[Dict[str, str]] = None,
|
1465
|
+
incremental_copy: bool = False,
|
1466
|
+
**kwargs: Any
|
1467
|
+
) -> Dict[str, Union[str, datetime]]:
|
1254
1468
|
"""Copies a blob from the given URL.
|
1255
1469
|
|
1256
1470
|
This operation returns a dictionary containing `copy_status` and `copy_id`,
|
@@ -1433,21 +1647,23 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1433
1647
|
:dedent: 16
|
1434
1648
|
:caption: Copy a blob from a URL.
|
1435
1649
|
"""
|
1436
|
-
options =
|
1437
|
-
source_url=
|
1650
|
+
options = _start_copy_from_url_options(
|
1651
|
+
source_url=source_url,
|
1438
1652
|
metadata=metadata,
|
1439
1653
|
incremental_copy=incremental_copy,
|
1440
1654
|
**kwargs)
|
1441
1655
|
try:
|
1442
1656
|
if incremental_copy:
|
1443
|
-
return await self._client.page_blob.copy_incremental(**options)
|
1444
|
-
return await self._client.blob.start_copy_from_url(**options)
|
1657
|
+
return cast(Dict[str, Union[str, datetime]], await self._client.page_blob.copy_incremental(**options))
|
1658
|
+
return cast(Dict[str, Union[str, datetime]], await self._client.blob.start_copy_from_url(**options))
|
1445
1659
|
except HttpResponseError as error:
|
1446
1660
|
process_storage_error(error)
|
1447
1661
|
|
1448
1662
|
@distributed_trace_async
|
1449
|
-
async def abort_copy(
|
1450
|
-
|
1663
|
+
async def abort_copy(
|
1664
|
+
self, copy_id: Union[str, Dict[str, Any], BlobProperties],
|
1665
|
+
**kwargs: Any
|
1666
|
+
) -> None:
|
1451
1667
|
"""Abort an ongoing copy operation.
|
1452
1668
|
|
1453
1669
|
This will leave a destination blob with zero length and full metadata.
|
@@ -1468,15 +1684,18 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1468
1684
|
:dedent: 16
|
1469
1685
|
:caption: Abort copying a blob from URL.
|
1470
1686
|
"""
|
1471
|
-
options =
|
1687
|
+
options = _abort_copy_options(copy_id, **kwargs)
|
1472
1688
|
try:
|
1473
1689
|
await self._client.blob.abort_copy_from_url(**options)
|
1474
1690
|
except HttpResponseError as error:
|
1475
1691
|
process_storage_error(error)
|
1476
1692
|
|
1477
1693
|
@distributed_trace_async
|
1478
|
-
async def acquire_lease(
|
1479
|
-
|
1694
|
+
async def acquire_lease(
|
1695
|
+
self, lease_duration: int =-1,
|
1696
|
+
lease_id: Optional[str] = None,
|
1697
|
+
**kwargs: Any
|
1698
|
+
) -> BlobLeaseClient:
|
1480
1699
|
"""Requests a new lease.
|
1481
1700
|
|
1482
1701
|
If the blob does not have an active lease, the Blob
|
@@ -1532,13 +1751,12 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1532
1751
|
:dedent: 12
|
1533
1752
|
:caption: Acquiring a lease on a blob.
|
1534
1753
|
"""
|
1535
|
-
lease = BlobLeaseClient(self, lease_id=lease_id)
|
1754
|
+
lease = BlobLeaseClient(self, lease_id=lease_id)
|
1536
1755
|
await lease.acquire(lease_duration=lease_duration, **kwargs)
|
1537
1756
|
return lease
|
1538
1757
|
|
1539
1758
|
@distributed_trace_async
|
1540
|
-
async def set_standard_blob_tier(self, standard_blob_tier, **kwargs):
|
1541
|
-
# type: (Union[str, StandardBlobTier], Any) -> None
|
1759
|
+
async def set_standard_blob_tier(self, standard_blob_tier: Union[str, "StandardBlobTier"], **kwargs: Any) -> None:
|
1542
1760
|
"""This operation sets the tier on a block blob.
|
1543
1761
|
|
1544
1762
|
A block blob's tier determines Hot/Cool/Archive storage type.
|
@@ -1590,19 +1808,18 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1590
1808
|
|
1591
1809
|
@distributed_trace_async
|
1592
1810
|
async def stage_block(
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
# type: (...) -> Dict[str, Any]
|
1811
|
+
self, block_id: str,
|
1812
|
+
data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]],
|
1813
|
+
length: Optional[int] = None,
|
1814
|
+
**kwargs: Any
|
1815
|
+
) -> Dict[str, Any]:
|
1599
1816
|
"""Creates a new block to be committed as part of a blob.
|
1600
1817
|
|
1601
1818
|
:param str block_id: A string value that identifies the block.
|
1602
1819
|
The string should be less than or equal to 64 bytes in size.
|
1603
1820
|
For a given blob, the block_id must be the same size for each block.
|
1604
1821
|
:param data: The blob data.
|
1605
|
-
:type data: Union[Iterable[AnyStr], IO[AnyStr]]
|
1822
|
+
:type data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]]
|
1606
1823
|
:param int length: Size of the block.
|
1607
1824
|
:keyword bool validate_content:
|
1608
1825
|
If true, calculates an MD5 hash for each chunk of the blob. The storage
|
@@ -1641,26 +1858,29 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1641
1858
|
:returns: Blob property dict.
|
1642
1859
|
:rtype: Dict[str, Any]
|
1643
1860
|
"""
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1861
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
1862
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
1863
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
1864
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
1865
|
+
options = _stage_block_options(
|
1866
|
+
block_id=block_id,
|
1867
|
+
data=data,
|
1647
1868
|
length=length,
|
1648
1869
|
**kwargs)
|
1649
1870
|
try:
|
1650
|
-
return await self._client.block_blob.stage_block(**options)
|
1871
|
+
return cast(Dict[str, Any], await self._client.block_blob.stage_block(**options))
|
1651
1872
|
except HttpResponseError as error:
|
1652
1873
|
process_storage_error(error)
|
1653
1874
|
|
1654
1875
|
@distributed_trace_async
|
1655
1876
|
async def stage_block_from_url(
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
# type: (...) -> Dict[str, Any]
|
1877
|
+
self, block_id: str,
|
1878
|
+
source_url: str,
|
1879
|
+
source_offset: Optional[int] = None,
|
1880
|
+
source_length: Optional[int] = None,
|
1881
|
+
source_content_md5: Optional[Union[bytes, bytearray]] = None,
|
1882
|
+
**kwargs: Any
|
1883
|
+
) -> Dict[str, Any]:
|
1664
1884
|
"""Creates a new block to be committed as part of a blob where
|
1665
1885
|
the contents are read from a URL.
|
1666
1886
|
|
@@ -1704,21 +1924,25 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1704
1924
|
:returns: Blob property dict.
|
1705
1925
|
:rtype: Dict[str, Any]
|
1706
1926
|
"""
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1927
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
1928
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
1929
|
+
options = _stage_block_from_url_options(
|
1930
|
+
block_id=block_id,
|
1931
|
+
source_url=source_url,
|
1710
1932
|
source_offset=source_offset,
|
1711
1933
|
source_length=source_length,
|
1712
1934
|
source_content_md5=source_content_md5,
|
1713
1935
|
**kwargs)
|
1714
1936
|
try:
|
1715
|
-
return await self._client.block_blob.stage_block_from_url(**options)
|
1937
|
+
return cast(Dict[str, Any], await self._client.block_blob.stage_block_from_url(**options))
|
1716
1938
|
except HttpResponseError as error:
|
1717
1939
|
process_storage_error(error)
|
1718
1940
|
|
1719
1941
|
@distributed_trace_async
|
1720
|
-
async def get_block_list(
|
1721
|
-
|
1942
|
+
async def get_block_list(
|
1943
|
+
self, block_list_type: str = "committed",
|
1944
|
+
**kwargs: Any
|
1945
|
+
) -> Tuple[List[BlobBlock], List[BlobBlock]]:
|
1722
1946
|
"""The Get Block List operation retrieves the list of blocks that have
|
1723
1947
|
been uploaded as part of a block blob.
|
1724
1948
|
|
@@ -1743,7 +1967,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1743
1967
|
see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
|
1744
1968
|
#other-client--per-operation-configuration>`__.
|
1745
1969
|
:returns: A tuple of two lists - committed and uncommitted blocks
|
1746
|
-
:rtype:
|
1970
|
+
:rtype: Tuple[List[BlobBlock], List[BlobBlock]]
|
1747
1971
|
"""
|
1748
1972
|
access_conditions = get_access_conditions(kwargs.pop('lease', None))
|
1749
1973
|
mod_conditions = get_modify_conditions(kwargs)
|
@@ -1757,16 +1981,15 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1757
1981
|
**kwargs)
|
1758
1982
|
except HttpResponseError as error:
|
1759
1983
|
process_storage_error(error)
|
1760
|
-
return
|
1984
|
+
return _get_block_list_result(blocks)
|
1761
1985
|
|
1762
1986
|
@distributed_trace_async
|
1763
|
-
async def commit_block_list(
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
# type: (...) -> Dict[str, Union[str, datetime]]
|
1987
|
+
async def commit_block_list(
|
1988
|
+
self, block_list: List[BlobBlock],
|
1989
|
+
content_settings: Optional["ContentSettings"] = None,
|
1990
|
+
metadata: Optional[Dict[str, str]] = None,
|
1991
|
+
**kwargs: Any
|
1992
|
+
) -> Dict[str, Union[str, datetime]]:
|
1770
1993
|
"""The Commit Block List operation writes a blob by specifying the list of
|
1771
1994
|
block IDs that make up the blob.
|
1772
1995
|
|
@@ -1859,19 +2082,22 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1859
2082
|
:returns: Blob-updated property dict (Etag and last modified).
|
1860
2083
|
:rtype: dict(str, Any)
|
1861
2084
|
"""
|
1862
|
-
|
1863
|
-
|
2085
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
2086
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
2087
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
2088
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
2089
|
+
options = _commit_block_list_options(
|
2090
|
+
block_list=block_list,
|
1864
2091
|
content_settings=content_settings,
|
1865
2092
|
metadata=metadata,
|
1866
2093
|
**kwargs)
|
1867
2094
|
try:
|
1868
|
-
return await self._client.block_blob.commit_block_list(**options)
|
2095
|
+
return cast(Dict[str, Any], await self._client.block_blob.commit_block_list(**options))
|
1869
2096
|
except HttpResponseError as error:
|
1870
2097
|
process_storage_error(error)
|
1871
2098
|
|
1872
2099
|
@distributed_trace_async
|
1873
|
-
async def set_premium_page_blob_tier(self, premium_page_blob_tier, **kwargs):
|
1874
|
-
# type: (Union[str, PremiumPageBlobTier], **Any) -> None
|
2100
|
+
async def set_premium_page_blob_tier(self, premium_page_blob_tier: "PremiumPageBlobTier", **kwargs: Any) -> None:
|
1875
2101
|
"""Sets the page blob tiers on the blob. This API is only supported for page blobs on premium accounts.
|
1876
2102
|
|
1877
2103
|
:param premium_page_blob_tier:
|
@@ -1912,8 +2138,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1912
2138
|
process_storage_error(error)
|
1913
2139
|
|
1914
2140
|
@distributed_trace_async
|
1915
|
-
async def set_blob_tags(self, tags=None, **kwargs):
|
1916
|
-
# type: (Optional[Dict[str, str]], **Any) -> Dict[str, Any]
|
2141
|
+
async def set_blob_tags(self, tags: Optional[Dict[str, str]] = None, **kwargs: Any) -> Dict[str, Any]:
|
1917
2142
|
"""The Set Tags operation enables users to set tags on a blob or specific blob version, but not snapshot.
|
1918
2143
|
Each call to this operation replaces all existing tags attached to the blob. To remove all
|
1919
2144
|
tags from the blob, call this operation with no tags set.
|
@@ -1954,15 +2179,15 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1954
2179
|
:returns: Blob-updated property dict (Etag and last modified)
|
1955
2180
|
:rtype: Dict[str, Any]
|
1956
2181
|
"""
|
1957
|
-
|
2182
|
+
version_id = get_version_id(self.version_id, kwargs)
|
2183
|
+
options = _set_blob_tags_options(version_id=version_id, tags=tags, **kwargs)
|
1958
2184
|
try:
|
1959
|
-
return await self._client.blob.set_tags(**options)
|
2185
|
+
return cast(Dict[str, Any], await self._client.blob.set_tags(**options))
|
1960
2186
|
except HttpResponseError as error:
|
1961
2187
|
process_storage_error(error)
|
1962
2188
|
|
1963
2189
|
@distributed_trace_async
|
1964
|
-
async def get_blob_tags(self, **kwargs):
|
1965
|
-
# type: (**Any) -> Dict[str, str]
|
2190
|
+
async def get_blob_tags(self, **kwargs: Any) -> Dict[str, str]:
|
1966
2191
|
"""The Get Tags operation enables users to get tags on a blob or specific blob version, but not snapshot.
|
1967
2192
|
|
1968
2193
|
.. versionadded:: 12.4.0
|
@@ -1987,21 +2212,21 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
1987
2212
|
:returns: Key value pairs of blob tags.
|
1988
2213
|
:rtype: Dict[str, str]
|
1989
2214
|
"""
|
1990
|
-
|
2215
|
+
version_id = get_version_id(self.version_id, kwargs)
|
2216
|
+
options = _get_blob_tags_options(version_id=version_id, snapshot=self.snapshot, **kwargs)
|
1991
2217
|
try:
|
1992
2218
|
_, tags = await self._client.blob.get_tags(**options)
|
1993
|
-
return parse_tags(tags) # pylint: disable=protected-access
|
2219
|
+
return cast(Dict[str, str], parse_tags(tags)) # pylint: disable=protected-access
|
1994
2220
|
except HttpResponseError as error:
|
1995
2221
|
process_storage_error(error)
|
1996
2222
|
|
1997
2223
|
@distributed_trace_async
|
1998
|
-
async def get_page_ranges(
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
# type: (...) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]
|
2224
|
+
async def get_page_ranges(
|
2225
|
+
self, offset: Optional[int] = None,
|
2226
|
+
length: Optional[int] = None,
|
2227
|
+
previous_snapshot_diff: Optional[Union[str, Dict[str, Any]]] = None,
|
2228
|
+
**kwargs: Any
|
2229
|
+
) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]:
|
2005
2230
|
"""DEPRECATED: Returns the list of valid page ranges for a Page Blob or snapshot
|
2006
2231
|
of a page blob.
|
2007
2232
|
|
@@ -2066,7 +2291,8 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2066
2291
|
DeprecationWarning
|
2067
2292
|
)
|
2068
2293
|
|
2069
|
-
options =
|
2294
|
+
options = _get_page_ranges_options(
|
2295
|
+
snapshot=self.snapshot,
|
2070
2296
|
offset=offset,
|
2071
2297
|
length=length,
|
2072
2298
|
previous_snapshot_diff=previous_snapshot_diff,
|
@@ -2082,13 +2308,13 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2082
2308
|
|
2083
2309
|
@distributed_trace
|
2084
2310
|
def list_page_ranges(
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2311
|
+
self,
|
2312
|
+
*,
|
2313
|
+
offset: Optional[int] = None,
|
2314
|
+
length: Optional[int] = None,
|
2315
|
+
previous_snapshot: Optional[Union[str, Dict[str, Any]]] = None,
|
2316
|
+
**kwargs: Any
|
2317
|
+
) -> AsyncItemPaged[PageRange]:
|
2092
2318
|
"""Returns the list of valid page ranges for a Page Blob or snapshot
|
2093
2319
|
of a page blob. If `previous_snapshot` is specified, the result will be
|
2094
2320
|
a diff of changes between the target blob and the previous snapshot.
|
@@ -2152,7 +2378,8 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2152
2378
|
:rtype: ~azure.core.paging.ItemPaged[~azure.storage.blob.PageRange]
|
2153
2379
|
"""
|
2154
2380
|
results_per_page = kwargs.pop('results_per_page', None)
|
2155
|
-
options =
|
2381
|
+
options = _get_page_ranges_options(
|
2382
|
+
snapshot=self.snapshot,
|
2156
2383
|
offset=offset,
|
2157
2384
|
length=length,
|
2158
2385
|
previous_snapshot_diff=previous_snapshot,
|
@@ -2172,12 +2399,11 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2172
2399
|
|
2173
2400
|
@distributed_trace_async
|
2174
2401
|
async def get_page_range_diff_for_managed_disk(
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
# type: (...) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]
|
2402
|
+
self, previous_snapshot_url: str,
|
2403
|
+
offset: Optional[int] = None,
|
2404
|
+
length: Optional[int] = None,
|
2405
|
+
**kwargs: Any
|
2406
|
+
) -> Tuple[List[Dict[str, int]], List[Dict[str, int]]]:
|
2181
2407
|
"""Returns the list of valid page ranges for a managed disk or snapshot.
|
2182
2408
|
|
2183
2409
|
.. note::
|
@@ -2236,7 +2462,8 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2236
2462
|
The first element are filled page ranges, the 2nd element is cleared page ranges.
|
2237
2463
|
:rtype: tuple(list(dict(str, str), list(dict(str, str))
|
2238
2464
|
"""
|
2239
|
-
options =
|
2465
|
+
options = _get_page_ranges_options(
|
2466
|
+
snapshot=self.snapshot,
|
2240
2467
|
offset=offset,
|
2241
2468
|
length=length,
|
2242
2469
|
prev_snapshot_url=previous_snapshot_url,
|
@@ -2248,12 +2475,11 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2248
2475
|
return get_page_ranges_result(ranges)
|
2249
2476
|
|
2250
2477
|
@distributed_trace_async
|
2251
|
-
async def set_sequence_number(
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
# type: (...) -> Dict[str, Union[str, datetime]]
|
2478
|
+
async def set_sequence_number(
|
2479
|
+
self, sequence_number_action: Union[str, "SequenceNumberAction"],
|
2480
|
+
sequence_number: Optional[str] = None,
|
2481
|
+
**kwargs: Any
|
2482
|
+
) -> Dict[str, Union[str, datetime]]:
|
2257
2483
|
"""Sets the blob sequence number.
|
2258
2484
|
|
2259
2485
|
:param str sequence_number_action:
|
@@ -2299,16 +2525,14 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2299
2525
|
:returns: Blob-updated property dict (Etag and last modified).
|
2300
2526
|
:rtype: dict(str, Any)
|
2301
2527
|
"""
|
2302
|
-
options =
|
2303
|
-
sequence_number_action, sequence_number=sequence_number, **kwargs)
|
2528
|
+
options = _set_sequence_number_options(sequence_number_action, sequence_number=sequence_number, **kwargs)
|
2304
2529
|
try:
|
2305
|
-
return await self._client.page_blob.update_sequence_number(**options)
|
2530
|
+
return cast(Dict[str, Any], await self._client.page_blob.update_sequence_number(**options))
|
2306
2531
|
except HttpResponseError as error:
|
2307
2532
|
process_storage_error(error)
|
2308
2533
|
|
2309
2534
|
@distributed_trace_async
|
2310
|
-
async def resize_blob(self, size, **kwargs):
|
2311
|
-
# type: (int, Any) -> Dict[str, Union[str, datetime]]
|
2535
|
+
async def resize_blob(self, size: int, **kwargs: Any) -> Dict[str, Union[str, datetime]]:
|
2312
2536
|
"""Resizes a page blob to the specified size.
|
2313
2537
|
|
2314
2538
|
If the specified value is less than the current size of the blob,
|
@@ -2357,20 +2581,21 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2357
2581
|
:returns: Blob-updated property dict (Etag and last modified).
|
2358
2582
|
:rtype: dict(str, Any)
|
2359
2583
|
"""
|
2360
|
-
|
2584
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
2585
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
2586
|
+
options = _resize_blob_options(size=size, **kwargs)
|
2361
2587
|
try:
|
2362
|
-
return await self._client.page_blob.resize(**options)
|
2588
|
+
return cast(Dict[str, Any], await self._client.page_blob.resize(**options))
|
2363
2589
|
except HttpResponseError as error:
|
2364
2590
|
process_storage_error(error)
|
2365
2591
|
|
2366
2592
|
@distributed_trace_async
|
2367
|
-
async def upload_page(
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2372
|
-
|
2373
|
-
# type: (...) -> Dict[str, Union[str, datetime]]
|
2593
|
+
async def upload_page(
|
2594
|
+
self, page: bytes,
|
2595
|
+
offset: int,
|
2596
|
+
length: int,
|
2597
|
+
**kwargs: Any
|
2598
|
+
) -> Dict[str, Union[str, datetime]]:
|
2374
2599
|
"""The Upload Pages operation writes a range of pages to a page blob.
|
2375
2600
|
|
2376
2601
|
:param bytes page:
|
@@ -2452,24 +2677,28 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2452
2677
|
:returns: Blob-updated property dict (Etag and last modified).
|
2453
2678
|
:rtype: dict(str, Any)
|
2454
2679
|
"""
|
2455
|
-
|
2680
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
2681
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
2682
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
2683
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
2684
|
+
options = _upload_page_options(
|
2456
2685
|
page=page,
|
2457
2686
|
offset=offset,
|
2458
2687
|
length=length,
|
2459
2688
|
**kwargs)
|
2460
2689
|
try:
|
2461
|
-
return await self._client.page_blob.upload_pages(**options)
|
2690
|
+
return cast(Dict[str, Any], await self._client.page_blob.upload_pages(**options))
|
2462
2691
|
except HttpResponseError as error:
|
2463
2692
|
process_storage_error(error)
|
2464
2693
|
|
2465
2694
|
@distributed_trace_async
|
2466
|
-
async def upload_pages_from_url(
|
2467
|
-
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2472
|
-
|
2695
|
+
async def upload_pages_from_url(
|
2696
|
+
self, source_url: str,
|
2697
|
+
offset: int,
|
2698
|
+
length: int,
|
2699
|
+
source_offset: int,
|
2700
|
+
**kwargs: Any
|
2701
|
+
) -> Dict[str, Any]:
|
2473
2702
|
"""
|
2474
2703
|
The Upload Pages operation writes a range of pages to a page blob where
|
2475
2704
|
the contents are read from a URL.
|
@@ -2571,21 +2800,24 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2571
2800
|
:rtype: Dict[str, Any]
|
2572
2801
|
"""
|
2573
2802
|
|
2574
|
-
|
2575
|
-
|
2803
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
2804
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
2805
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
2806
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
2807
|
+
options = _upload_pages_from_url_options(
|
2808
|
+
source_url=source_url,
|
2576
2809
|
offset=offset,
|
2577
2810
|
length=length,
|
2578
2811
|
source_offset=source_offset,
|
2579
2812
|
**kwargs
|
2580
2813
|
)
|
2581
2814
|
try:
|
2582
|
-
return await self._client.page_blob.upload_pages_from_url(**options)
|
2815
|
+
return cast(Dict[str, Any], await self._client.page_blob.upload_pages_from_url(**options))
|
2583
2816
|
except HttpResponseError as error:
|
2584
2817
|
process_storage_error(error)
|
2585
2818
|
|
2586
2819
|
@distributed_trace_async
|
2587
|
-
async def clear_page(self, offset, length, **kwargs):
|
2588
|
-
# type: (int, int, Any) -> Dict[str, Union[str, datetime]]
|
2820
|
+
async def clear_page(self, offset: int, length: int, **kwargs: Any) -> Dict[str, Union[str, datetime]]:
|
2589
2821
|
"""Clears a range of pages.
|
2590
2822
|
|
2591
2823
|
:param int offset:
|
@@ -2648,19 +2880,26 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2648
2880
|
:returns: Blob-updated property dict (Etag and last modified).
|
2649
2881
|
:rtype: dict(str, Any)
|
2650
2882
|
"""
|
2651
|
-
|
2883
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
2884
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
2885
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
2886
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
2887
|
+
options = _clear_page_options(
|
2888
|
+
offset=offset,
|
2889
|
+
length=length,
|
2890
|
+
**kwargs
|
2891
|
+
)
|
2652
2892
|
try:
|
2653
|
-
return await self._client.page_blob.clear_pages(**options)
|
2893
|
+
return cast(Dict[str, Any], await self._client.page_blob.clear_pages(**options))
|
2654
2894
|
except HttpResponseError as error:
|
2655
2895
|
process_storage_error(error)
|
2656
2896
|
|
2657
2897
|
@distributed_trace_async
|
2658
|
-
async def append_block(
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
# type: (...) -> Dict[str, Union[str, datetime, int]]
|
2898
|
+
async def append_block(
|
2899
|
+
self, data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]],
|
2900
|
+
length: Optional[int] = None,
|
2901
|
+
**kwargs: Any
|
2902
|
+
) -> Dict[str, Union[str, datetime, int]]:
|
2664
2903
|
"""Commits a new block of data to the end of the existing append blob.
|
2665
2904
|
|
2666
2905
|
:param data:
|
@@ -2738,22 +2977,27 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2738
2977
|
:returns: Blob-updated property dict (Etag, last modified, append offset, committed block count).
|
2739
2978
|
:rtype: dict(str, Any)
|
2740
2979
|
"""
|
2741
|
-
|
2742
|
-
|
2980
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
2981
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
2982
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
2983
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
2984
|
+
options = _append_block_options(
|
2985
|
+
data=data,
|
2743
2986
|
length=length,
|
2744
2987
|
**kwargs
|
2745
2988
|
)
|
2746
2989
|
try:
|
2747
|
-
return await self._client.append_blob.append_block(**options)
|
2990
|
+
return cast(Dict[str, Any], await self._client.append_blob.append_block(**options))
|
2748
2991
|
except HttpResponseError as error:
|
2749
2992
|
process_storage_error(error)
|
2750
2993
|
|
2751
2994
|
@distributed_trace_async
|
2752
|
-
async def append_block_from_url(
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2995
|
+
async def append_block_from_url(
|
2996
|
+
self, copy_source_url: str,
|
2997
|
+
source_offset: Optional[int] = None,
|
2998
|
+
source_length: Optional[int] = None,
|
2999
|
+
**kwargs: Any
|
3000
|
+
) -> Dict[str, Union[str, datetime, int]]:
|
2757
3001
|
"""
|
2758
3002
|
Creates a new block to be committed as part of a blob, where the contents are read from a source url.
|
2759
3003
|
|
@@ -2848,20 +3092,24 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2848
3092
|
:returns: Result after appending a new block.
|
2849
3093
|
:rtype: Dict[str, Union[str, datetime, int]]
|
2850
3094
|
"""
|
2851
|
-
|
2852
|
-
|
3095
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
3096
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
3097
|
+
if kwargs.get('cpk') and self.scheme.lower() != 'https':
|
3098
|
+
raise ValueError("Customer provided encryption key must be used over HTTPS.")
|
3099
|
+
options = _append_block_from_url_options(
|
3100
|
+
copy_source_url=copy_source_url,
|
2853
3101
|
source_offset=source_offset,
|
2854
3102
|
source_length=source_length,
|
2855
3103
|
**kwargs
|
2856
3104
|
)
|
2857
3105
|
try:
|
2858
|
-
return
|
3106
|
+
return cast(Dict[str, Union[str, datetime, int]],
|
3107
|
+
await self._client.append_blob.append_block_from_url(**options))
|
2859
3108
|
except HttpResponseError as error:
|
2860
3109
|
process_storage_error(error)
|
2861
3110
|
|
2862
3111
|
@distributed_trace_async
|
2863
|
-
async def seal_append_blob(self, **kwargs):
|
2864
|
-
# type: (...) -> Dict[str, Union[str, datetime, int]]
|
3112
|
+
async def seal_append_blob(self, **kwargs: Any) -> Dict[str, Union[str, datetime, int]]:
|
2865
3113
|
"""The Seal operation seals the Append Blob to make it read-only.
|
2866
3114
|
|
2867
3115
|
.. versionadded:: 12.4.0
|
@@ -2902,14 +3150,15 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2902
3150
|
:returns: Blob-updated property dict (Etag, last modified, append offset, committed block count).
|
2903
3151
|
:rtype: dict(str, Any)
|
2904
3152
|
"""
|
2905
|
-
|
3153
|
+
if self.require_encryption or (self.key_encryption_key is not None):
|
3154
|
+
raise ValueError(_ERROR_UNSUPPORTED_METHOD_FOR_ENCRYPTION)
|
3155
|
+
options = _seal_append_blob_options(**kwargs)
|
2906
3156
|
try:
|
2907
|
-
return await self._client.append_blob.seal(**options)
|
3157
|
+
return cast(Dict[str, Any], await self._client.append_blob.seal(**options))
|
2908
3158
|
except HttpResponseError as error:
|
2909
3159
|
process_storage_error(error)
|
2910
3160
|
|
2911
|
-
def _get_container_client(self)
|
2912
|
-
# type: (...) -> ContainerClient
|
3161
|
+
def _get_container_client(self) -> "ContainerClient":
|
2913
3162
|
"""Get a client to interact with the blob's parent container.
|
2914
3163
|
|
2915
3164
|
The container need not already exist. Defaults to current blob's credentials.
|
@@ -2930,7 +3179,8 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
|
|
2930
3179
|
if not isinstance(self._pipeline._transport, AsyncTransportWrapper): # pylint: disable = protected-access
|
2931
3180
|
_pipeline = AsyncPipeline(
|
2932
3181
|
transport=AsyncTransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
|
2933
|
-
policies=
|
3182
|
+
policies=cast(Iterable["AsyncHTTPPolicy"],
|
3183
|
+
self._pipeline._impl_policies) # pylint: disable = protected-access
|
2934
3184
|
)
|
2935
3185
|
else:
|
2936
3186
|
_pipeline = self._pipeline # pylint: disable = protected-access
|