azure-storage-blob 12.21.0b1__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.
Files changed (43) hide show
  1. azure/storage/blob/__init__.py +19 -18
  2. azure/storage/blob/_blob_client.py +470 -1555
  3. azure/storage/blob/_blob_client_helpers.py +1242 -0
  4. azure/storage/blob/_blob_service_client.py +93 -112
  5. azure/storage/blob/_blob_service_client_helpers.py +27 -0
  6. azure/storage/blob/_container_client.py +169 -376
  7. azure/storage/blob/_container_client_helpers.py +261 -0
  8. azure/storage/blob/_deserialize.py +68 -44
  9. azure/storage/blob/_download.py +375 -241
  10. azure/storage/blob/_encryption.py +14 -7
  11. azure/storage/blob/_generated/py.typed +1 -0
  12. azure/storage/blob/_lease.py +52 -63
  13. azure/storage/blob/_list_blobs_helper.py +129 -135
  14. azure/storage/blob/_models.py +480 -277
  15. azure/storage/blob/_quick_query_helper.py +30 -31
  16. azure/storage/blob/_serialize.py +38 -56
  17. azure/storage/blob/_shared/avro/datafile.py +1 -1
  18. azure/storage/blob/_shared/avro/datafile_async.py +1 -1
  19. azure/storage/blob/_shared/base_client.py +1 -1
  20. azure/storage/blob/_shared/base_client_async.py +1 -1
  21. azure/storage/blob/_shared/policies.py +8 -6
  22. azure/storage/blob/_shared/policies_async.py +3 -1
  23. azure/storage/blob/_shared/response_handlers.py +6 -2
  24. azure/storage/blob/_shared/shared_access_signature.py +2 -2
  25. azure/storage/blob/_shared/uploads.py +1 -1
  26. azure/storage/blob/_shared/uploads_async.py +1 -1
  27. azure/storage/blob/_shared_access_signature.py +70 -53
  28. azure/storage/blob/_upload_helpers.py +75 -68
  29. azure/storage/blob/_version.py +1 -1
  30. azure/storage/blob/aio/__init__.py +19 -11
  31. azure/storage/blob/aio/_blob_client_async.py +554 -301
  32. azure/storage/blob/aio/_blob_service_client_async.py +148 -97
  33. azure/storage/blob/aio/_container_client_async.py +282 -139
  34. azure/storage/blob/aio/_download_async.py +408 -283
  35. azure/storage/blob/aio/_lease_async.py +61 -60
  36. azure/storage/blob/aio/_list_blobs_helper.py +94 -96
  37. azure/storage/blob/aio/_models.py +60 -38
  38. azure/storage/blob/aio/_upload_helpers.py +75 -66
  39. {azure_storage_blob-12.21.0b1.dist-info → azure_storage_blob-12.22.0.dist-info}/METADATA +7 -7
  40. {azure_storage_blob-12.21.0b1.dist-info → azure_storage_blob-12.22.0.dist-info}/RECORD +43 -39
  41. {azure_storage_blob-12.21.0b1.dist-info → azure_storage_blob-12.22.0.dist-info}/WHEEL +1 -1
  42. {azure_storage_blob-12.21.0b1.dist-info → azure_storage_blob-12.22.0.dist-info}/LICENSE +0 -0
  43. {azure_storage_blob-12.21.0b1.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 ( # pylint: disable=unused-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 datetime import datetime
49
- from .._models import ( # pylint: disable=unused-import
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
- StandardBlobTier,
54
- SequenceNumberAction
87
+ SequenceNumberAction,
88
+ StandardBlobTier
55
89
  )
56
90
 
57
91
 
58
- class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptionMixin): # pylint: disable=too-many-public-methods
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
- ) -> None:
165
+ ) -> None:
132
166
  kwargs['retry_policy'] = kwargs.get('retry_policy') or ExponentialRetry(**kwargs)
133
- super(BlobClient, self).__init__(
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
- snapshot=snapshot,
138
- credential=credential,
139
- **kwargs)
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): # type: ignore
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 await self._client.blob.get_account_info(cls=return_response_headers, **kwargs) # type: ignore
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.
@@ -167,9 +318,9 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
167
318
  :param str source_url:
168
319
  A URL of up to 2 KB in length that specifies a file or blob.
169
320
  The value should be URL-encoded as it would appear in a request URI.
170
- If the source is in another account, the source must either be public
171
- or must be authenticated via a shared access signature. If the source
172
- is public, no authentication is required.
321
+ The source must either be public or must be authenticated via a shared
322
+ access signature as part of the url or using the source_authorization keyword.
323
+ If the source is public, no authentication is required.
173
324
  Examples:
174
325
  https://myaccount.blob.core.windows.net/mycontainer/myblob
175
326
 
@@ -186,7 +337,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
186
337
  The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
187
338
  and tag values must be between 0 and 256 characters.
188
339
  Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
189
- space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
340
+ space (' '), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
190
341
  :paramtype tags: dict(str, str)
191
342
  :keyword bytearray source_content_md5:
192
343
  Specify the md5 that is used to verify the integrity of the source bytes.
@@ -234,7 +385,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
234
385
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
235
386
  This value is not tracked or validated on the client. To configure client-side network timesouts
236
387
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
237
- #other-client--per-operation-configuration>`_.
388
+ #other-client--per-operation-configuration>`__.
238
389
  :keyword ~azure.storage.blob.ContentSettings content_settings:
239
390
  ContentSettings object used to set blob properties. Used to set content type, encoding,
240
391
  language, disposition, md5, and cache control.
@@ -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
- options = self._upload_blob_from_url_options(
261
- source_url=self._encode_source_url(source_url),
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
- self, data: Union[bytes, str, Iterable[AnyStr], AsyncIterable[AnyStr], IO[AnyStr]],
271
- blob_type: Union[str, BlobType] = BlobType.BlockBlob,
272
- length: Optional[int] = None,
273
- metadata: Optional[Dict[str, str]] = None,
274
- **kwargs
275
- ) -> Dict[str, Any]:
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:
@@ -289,7 +443,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
289
443
  The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
290
444
  and tag values must be between 0 and 256 characters.
291
445
  Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
292
- space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
446
+ space (' '), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
293
447
 
294
448
  .. versionadded:: 12.4.0
295
449
 
@@ -395,7 +549,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
395
549
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
396
550
  This value is not tracked or validated on the client. To configure client-side network timesouts
397
551
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
398
- #other-client--per-operation-configuration>`_. This method may make multiple calls to the service and
552
+ #other-client--per-operation-configuration>`__. This method may make multiple calls to the service and
399
553
  the timeout will apply to each call individually.
400
554
  multiple calls to the Azure service and the timeout will apply to
401
555
  each call individually.
@@ -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
- options = self._upload_blob_options(
415
- data,
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
- self, offset: int = None,
429
- length: int = None,
430
- *,
431
- encoding: str,
432
- **kwargs) -> StorageStreamDownloader[str]:
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
- self, offset: int = None,
438
- length: int = None,
439
- *,
440
- encoding: None = None,
441
- **kwargs) -> StorageStreamDownloader[bytes]:
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
- self, offset: int = None,
447
- length: int = None,
448
- *,
449
- encoding: Optional[str] = None,
450
- **kwargs) -> StorageStreamDownloader:
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.
@@ -463,6 +633,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
463
633
  value that, when present, specifies the version of the blob to download.
464
634
 
465
635
  .. versionadded:: 12.4.0
636
+
466
637
  This keyword argument was introduced in API version '2019-12-12'.
467
638
 
468
639
  :keyword bool validate_content:
@@ -521,7 +692,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
521
692
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
522
693
  This value is not tracked or validated on the client. To configure client-side network timesouts
523
694
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
524
- #other-client--per-operation-configuration>`_. This method may make multiple calls to the service and
695
+ #other-client--per-operation-configuration>`__. This method may make multiple calls to the service and
525
696
  the timeout will apply to each call individually.
526
697
  multiple calls to the Azure service and the timeout will apply to
527
698
  each call individually.
@@ -537,18 +708,35 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
537
708
  :dedent: 16
538
709
  :caption: Download a blob.
539
710
  """
540
- options = self._download_blob_options(
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),
541
721
  offset=offset,
542
722
  length=length,
543
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,
544
733
  **kwargs)
545
734
  downloader = StorageStreamDownloader(**options)
546
735
  await downloader._setup() # pylint: disable=protected-access
547
736
  return downloader
548
737
 
549
738
  @distributed_trace_async
550
- async def delete_blob(self, delete_snapshots=None, **kwargs):
551
- # type: (str, Any) -> None
739
+ async def delete_blob(self, delete_snapshots: Optional[str] = None, **kwargs: Any) -> None:
552
740
  """Marks the specified blob for deletion.
553
741
 
554
742
  The blob is later deleted during garbage collection.
@@ -571,6 +759,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
571
759
  value that, when present, specifies the version of the blob to delete.
572
760
 
573
761
  .. versionadded:: 12.4.0
762
+
574
763
  This keyword argument was introduced in API version '2019-12-12'.
575
764
 
576
765
  :keyword lease:
@@ -606,7 +795,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
606
795
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
607
796
  This value is not tracked or validated on the client. To configure client-side network timesouts
608
797
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
609
- #other-client--per-operation-configuration>`_.
798
+ #other-client--per-operation-configuration>`__.
610
799
  :rtype: None
611
800
 
612
801
  .. admonition:: Example:
@@ -618,15 +807,18 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
618
807
  :dedent: 16
619
808
  :caption: Delete a blob.
620
809
  """
621
- options = self._delete_blob_options(delete_snapshots=delete_snapshots, **kwargs)
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)
622
815
  try:
623
816
  await self._client.blob.delete(**options)
624
817
  except HttpResponseError as error:
625
818
  process_storage_error(error)
626
819
 
627
820
  @distributed_trace_async
628
- async def undelete_blob(self, **kwargs):
629
- # type: (Any) -> None
821
+ async def undelete_blob(self, **kwargs: Any) -> None:
630
822
  """Restores soft-deleted blobs or snapshots.
631
823
 
632
824
  Operation will only be successful if used within the specified number of days
@@ -641,7 +833,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
641
833
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
642
834
  This value is not tracked or validated on the client. To configure client-side network timesouts
643
835
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
644
- #other-client--per-operation-configuration>`_.
836
+ #other-client--per-operation-configuration>`__.
645
837
  :rtype: None
646
838
 
647
839
  .. admonition:: Example:
@@ -659,8 +851,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
659
851
  process_storage_error(error)
660
852
 
661
853
  @distributed_trace_async
662
- async def exists(self, **kwargs):
663
- # type: (**Any) -> bool
854
+ async def exists(self, **kwargs: Any) -> bool:
664
855
  """
665
856
  Returns True if a blob exists with the defined parameters, and returns
666
857
  False otherwise.
@@ -673,7 +864,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
673
864
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
674
865
  This value is not tracked or validated on the client. To configure client-side network timesouts
675
866
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
676
- #other-client--per-operation-configuration>`_.
867
+ #other-client--per-operation-configuration>`__.
677
868
  :returns: boolean
678
869
  :rtype: bool
679
870
  """
@@ -694,8 +885,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
694
885
  return False
695
886
 
696
887
  @distributed_trace_async
697
- async def get_blob_properties(self, **kwargs):
698
- # type: (Any) -> BlobProperties
888
+ async def get_blob_properties(self, **kwargs: Any) -> BlobProperties:
699
889
  """Returns all user-defined metadata, standard HTTP properties, and
700
890
  system properties for the blob. It does not return the content of the blob.
701
891
 
@@ -708,6 +898,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
708
898
  value that, when present, specifies the version of the blob to get properties.
709
899
 
710
900
  .. versionadded:: 12.4.0
901
+
711
902
  This keyword argument was introduced in API version '2019-12-12'.
712
903
 
713
904
  :keyword ~datetime.datetime if_modified_since:
@@ -743,7 +934,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
743
934
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
744
935
  This value is not tracked or validated on the client. To configure client-side network timesouts
745
936
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
746
- #other-client--per-operation-configuration>`_.
937
+ #other-client--per-operation-configuration>`__.
747
938
  :returns: BlobProperties
748
939
  :rtype: ~azure.storage.blob.BlobProperties
749
940
 
@@ -785,11 +976,13 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
785
976
  if isinstance(blob_props, BlobProperties):
786
977
  blob_props.container = self.container_name
787
978
  blob_props.snapshot = self.snapshot
788
- return blob_props # type: ignore
979
+ return cast(BlobProperties, blob_props)
789
980
 
790
981
  @distributed_trace_async
791
- async def set_http_headers(self, content_settings=None, **kwargs):
792
- # type: (Optional[ContentSettings], Any) -> None
982
+ async def set_http_headers(
983
+ self, content_settings: Optional["ContentSettings"] = None,
984
+ **kwargs: Any
985
+ ) -> Dict[str, Any]:
793
986
  """Sets system properties on the blob.
794
987
 
795
988
  If one property is set for the content_settings, all properties will be overridden.
@@ -829,19 +1022,21 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
829
1022
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
830
1023
  This value is not tracked or validated on the client. To configure client-side network timesouts
831
1024
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
832
- #other-client--per-operation-configuration>`_.
1025
+ #other-client--per-operation-configuration>`__.
833
1026
  :returns: Blob-updated property dict (Etag and last modified)
834
1027
  :rtype: Dict[str, Any]
835
1028
  """
836
- options = self._set_http_headers_options(content_settings=content_settings, **kwargs)
1029
+ options = _set_http_headers_options(content_settings=content_settings, **kwargs)
837
1030
  try:
838
- return await self._client.blob.set_http_headers(**options) # type: ignore
1031
+ return cast(Dict[str, Any], await self._client.blob.set_http_headers(**options))
839
1032
  except HttpResponseError as error:
840
1033
  process_storage_error(error)
841
1034
 
842
1035
  @distributed_trace_async
843
- async def set_blob_metadata(self, metadata=None, **kwargs):
844
- # type: (Optional[Dict[str, str]], Any) -> Dict[str, Union[str, datetime]]
1036
+ async def set_blob_metadata(
1037
+ self, metadata: Optional[Dict[str, str]] = None,
1038
+ **kwargs: Any
1039
+ ) -> Dict[str, Union[str, datetime]]:
845
1040
  """Sets user-defined metadata for the blob as one or more name-value pairs.
846
1041
 
847
1042
  :param metadata:
@@ -894,19 +1089,23 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
894
1089
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
895
1090
  This value is not tracked or validated on the client. To configure client-side network timesouts
896
1091
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
897
- #other-client--per-operation-configuration>`_.
1092
+ #other-client--per-operation-configuration>`__.
898
1093
  :returns: Blob-updated property dict (Etag and last modified)
899
1094
  :rtype: Dict[str, Union[str, datetime]]
900
1095
  """
901
- options = self._set_blob_metadata_options(metadata=metadata, **kwargs)
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)
902
1099
  try:
903
- return await self._client.blob.set_metadata(**options) # type: ignore
1100
+ return cast(Dict[str, Union[str, datetime]], await self._client.blob.set_metadata(**options))
904
1101
  except HttpResponseError as error:
905
1102
  process_storage_error(error)
906
1103
 
907
1104
  @distributed_trace_async
908
- async def set_immutability_policy(self, immutability_policy, **kwargs):
909
- # type: (ImmutabilityPolicy, **Any) -> Dict[str, str]
1105
+ async def set_immutability_policy(
1106
+ self, immutability_policy: "ImmutabilityPolicy",
1107
+ **kwargs: Any
1108
+ ) -> Dict[str, str]:
910
1109
  """The Set Immutability Policy operation sets the immutability policy on the blob.
911
1110
 
912
1111
  .. versionadded:: 12.10.0
@@ -923,18 +1122,18 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
923
1122
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
924
1123
  This value is not tracked or validated on the client. To configure client-side network timesouts
925
1124
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
926
- #other-client--per-operation-configuration>`_.
1125
+ #other-client--per-operation-configuration>`__.
927
1126
  :returns: Key value pairs of blob tags.
928
1127
  :rtype: Dict[str, str]
929
1128
  """
930
1129
 
931
1130
  kwargs['immutability_policy_expiry'] = immutability_policy.expiry_time
932
1131
  kwargs['immutability_policy_mode'] = immutability_policy.policy_mode
933
- return await self._client.blob.set_immutability_policy(cls=return_response_headers, **kwargs)
1132
+ return cast(Dict[str, str],
1133
+ await self._client.blob.set_immutability_policy(cls=return_response_headers, **kwargs))
934
1134
 
935
1135
  @distributed_trace_async
936
- async def delete_immutability_policy(self, **kwargs):
937
- # type: (**Any) -> None
1136
+ async def delete_immutability_policy(self, **kwargs: Any) -> None:
938
1137
  """The Delete Immutability Policy operation deletes the immutability policy on the blob.
939
1138
 
940
1139
  .. versionadded:: 12.10.0
@@ -945,7 +1144,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
945
1144
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
946
1145
  This value is not tracked or validated on the client. To configure client-side network timesouts
947
1146
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
948
- #other-client--per-operation-configuration>`_.
1147
+ #other-client--per-operation-configuration>`__.
949
1148
  :returns: Key value pairs of blob tags.
950
1149
  :rtype: Dict[str, str]
951
1150
  """
@@ -953,8 +1152,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
953
1152
  await self._client.blob.delete_immutability_policy(**kwargs)
954
1153
 
955
1154
  @distributed_trace_async
956
- async def set_legal_hold(self, legal_hold, **kwargs):
957
- # 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]]:
958
1156
  """The Set Legal Hold operation sets a legal hold on the blob.
959
1157
 
960
1158
  .. versionadded:: 12.10.0
@@ -967,22 +1165,22 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
967
1165
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
968
1166
  This value is not tracked or validated on the client. To configure client-side network timesouts
969
1167
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
970
- #other-client--per-operation-configuration>`_.
1168
+ #other-client--per-operation-configuration>`__.
971
1169
  :returns: Key value pairs of blob tags.
972
1170
  :rtype: Dict[str, Union[str, datetime, bool]]
973
1171
  """
974
1172
 
975
- return await self._client.blob.set_legal_hold(legal_hold, cls=return_response_headers, **kwargs)
1173
+ return cast(Dict[str, Union[str, datetime, bool]],
1174
+ await self._client.blob.set_legal_hold(legal_hold, cls=return_response_headers, **kwargs))
976
1175
 
977
1176
  @distributed_trace_async
978
- async def create_page_blob( # type: ignore
979
- self, size, # type: int
980
- content_settings=None, # type: Optional[ContentSettings]
981
- metadata=None, # type: Optional[Dict[str, str]]
982
- premium_page_blob_tier=None, # type: Optional[Union[str, PremiumPageBlobTier]]
983
- **kwargs
984
- ):
985
- # 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]]:
986
1184
  """Creates a new Page Blob of the specified size.
987
1185
 
988
1186
  :param int size:
@@ -1003,7 +1201,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1003
1201
  The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
1004
1202
  and tag values must be between 0 and 256 characters.
1005
1203
  Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
1006
- space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
1204
+ space (' '), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
1007
1205
 
1008
1206
  .. versionadded:: 12.4.0
1009
1207
 
@@ -1063,24 +1261,31 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1063
1261
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1064
1262
  This value is not tracked or validated on the client. To configure client-side network timesouts
1065
1263
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1066
- #other-client--per-operation-configuration>`_.
1264
+ #other-client--per-operation-configuration>`__.
1067
1265
  :returns: Blob-updated property dict (Etag and last modified).
1068
1266
  :rtype: dict[str, Any]
1069
1267
  """
1070
- options = self._create_page_blob_options(
1071
- size,
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,
1072
1274
  content_settings=content_settings,
1073
1275
  metadata=metadata,
1074
1276
  premium_page_blob_tier=premium_page_blob_tier,
1075
1277
  **kwargs)
1076
1278
  try:
1077
- return await self._client.page_blob.create(**options) # type: ignore
1279
+ return cast(Dict[str, Any], await self._client.page_blob.create(**options))
1078
1280
  except HttpResponseError as error:
1079
1281
  process_storage_error(error)
1080
1282
 
1081
1283
  @distributed_trace_async
1082
- async def create_append_blob(self, content_settings=None, metadata=None, **kwargs):
1083
- # type: (Optional[ContentSettings], Optional[Dict[str, str]], Any) -> Dict[str, Union[str, datetime]]
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]]:
1084
1289
  """Creates a new Append Blob. This operation creates a new 0-length append blob. The content
1085
1290
  of any existing blob is overwritten with the newly initialized append blob. To add content to
1086
1291
  the append blob, call the :func:`append_block` or :func:`append_block_from_url` method.
@@ -1096,7 +1301,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1096
1301
  The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
1097
1302
  and tag values must be between 0 and 256 characters.
1098
1303
  Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
1099
- space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
1304
+ space (' '), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
1100
1305
 
1101
1306
  .. versionadded:: 12.4.0
1102
1307
 
@@ -1152,22 +1357,28 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1152
1357
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1153
1358
  This value is not tracked or validated on the client. To configure client-side network timesouts
1154
1359
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1155
- #other-client--per-operation-configuration>`_.
1360
+ #other-client--per-operation-configuration>`__.
1156
1361
  :returns: Blob-updated property dict (Etag and last modified).
1157
1362
  :rtype: dict[str, Any]
1158
1363
  """
1159
- options = self._create_append_blob_options(
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(
1160
1369
  content_settings=content_settings,
1161
1370
  metadata=metadata,
1162
1371
  **kwargs)
1163
1372
  try:
1164
- return await self._client.append_blob.create(**options) # type: ignore
1373
+ return cast(Dict[str, Union[str, datetime]], await self._client.append_blob.create(**options))
1165
1374
  except HttpResponseError as error:
1166
1375
  process_storage_error(error)
1167
1376
 
1168
1377
  @distributed_trace_async
1169
- async def create_snapshot(self, metadata=None, **kwargs):
1170
- # type: (Optional[Dict[str, str]], Any) -> Dict[str, Union[str, datetime]]
1378
+ async def create_snapshot(
1379
+ self, metadata: Optional[Dict[str, str]] = None,
1380
+ **kwargs: Any
1381
+ ) -> Dict[str, Union[str, datetime]]:
1171
1382
  """Creates a snapshot of the blob.
1172
1383
 
1173
1384
  A snapshot is a read-only version of a blob that's taken at a point in time.
@@ -1226,7 +1437,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1226
1437
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1227
1438
  This value is not tracked or validated on the client. To configure client-side network timesouts
1228
1439
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1229
- #other-client--per-operation-configuration>`_.
1440
+ #other-client--per-operation-configuration>`__.
1230
1441
  :returns: Blob-updated property dict (Snapshot ID, Etag, and last modified).
1231
1442
  :rtype: dict[str, Any]
1232
1443
 
@@ -1239,15 +1450,21 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1239
1450
  :dedent: 12
1240
1451
  :caption: Create a snapshot of the blob.
1241
1452
  """
1242
- options = self._create_snapshot_options(metadata=metadata, **kwargs)
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)
1243
1456
  try:
1244
- return await self._client.blob.create_snapshot(**options) # type: ignore
1457
+ return cast(Dict[str, Any], await self._client.blob.create_snapshot(**options))
1245
1458
  except HttpResponseError as error:
1246
1459
  process_storage_error(error)
1247
1460
 
1248
1461
  @distributed_trace_async
1249
- async def start_copy_from_url(self, source_url, metadata=None, incremental_copy=False, **kwargs):
1250
- # type: (str, Optional[Dict[str, str]], bool, Any) -> Dict[str, Union[str, datetime]]
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]]:
1251
1468
  """Copies a blob from the given URL.
1252
1469
 
1253
1470
  This operation returns a dictionary containing `copy_status` and `copy_id`,
@@ -1308,7 +1525,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1308
1525
  The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
1309
1526
  and tag values must be between 0 and 256 characters.
1310
1527
  Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
1311
- space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_).
1528
+ space (' '), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_).
1312
1529
 
1313
1530
  The (case-sensitive) literal "COPY" can instead be passed to copy tags from the source blob.
1314
1531
  This option is only available when `incremental_copy=False` and `requires_sync=True`.
@@ -1386,7 +1603,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1386
1603
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1387
1604
  This value is not tracked or validated on the client. To configure client-side network timesouts
1388
1605
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1389
- #other-client--per-operation-configuration>`_.
1606
+ #other-client--per-operation-configuration>`__.
1390
1607
  :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier:
1391
1608
  A page blob tier value to set the blob to. The tier correlates to the size of the
1392
1609
  blob and number of allowed IOPS. This is only applicable to page blobs on
@@ -1430,21 +1647,23 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1430
1647
  :dedent: 16
1431
1648
  :caption: Copy a blob from a URL.
1432
1649
  """
1433
- options = self._start_copy_from_url_options(
1434
- source_url=self._encode_source_url(source_url),
1650
+ options = _start_copy_from_url_options(
1651
+ source_url=source_url,
1435
1652
  metadata=metadata,
1436
1653
  incremental_copy=incremental_copy,
1437
1654
  **kwargs)
1438
1655
  try:
1439
1656
  if incremental_copy:
1440
- return await self._client.page_blob.copy_incremental(**options)
1441
- 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))
1442
1659
  except HttpResponseError as error:
1443
1660
  process_storage_error(error)
1444
1661
 
1445
1662
  @distributed_trace_async
1446
- async def abort_copy(self, copy_id, **kwargs):
1447
- # type: (Union[str, Dict[str, Any], BlobProperties], Any) -> None
1663
+ async def abort_copy(
1664
+ self, copy_id: Union[str, Dict[str, Any], BlobProperties],
1665
+ **kwargs: Any
1666
+ ) -> None:
1448
1667
  """Abort an ongoing copy operation.
1449
1668
 
1450
1669
  This will leave a destination blob with zero length and full metadata.
@@ -1465,15 +1684,18 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1465
1684
  :dedent: 16
1466
1685
  :caption: Abort copying a blob from URL.
1467
1686
  """
1468
- options = self._abort_copy_options(copy_id, **kwargs)
1687
+ options = _abort_copy_options(copy_id, **kwargs)
1469
1688
  try:
1470
1689
  await self._client.blob.abort_copy_from_url(**options)
1471
1690
  except HttpResponseError as error:
1472
1691
  process_storage_error(error)
1473
1692
 
1474
1693
  @distributed_trace_async
1475
- async def acquire_lease(self, lease_duration=-1, lease_id=None, **kwargs):
1476
- # type: (int, Optional[str], Any) -> BlobLeaseClient
1694
+ async def acquire_lease(
1695
+ self, lease_duration: int =-1,
1696
+ lease_id: Optional[str] = None,
1697
+ **kwargs: Any
1698
+ ) -> BlobLeaseClient:
1477
1699
  """Requests a new lease.
1478
1700
 
1479
1701
  If the blob does not have an active lease, the Blob
@@ -1516,7 +1738,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1516
1738
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1517
1739
  This value is not tracked or validated on the client. To configure client-side network timesouts
1518
1740
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1519
- #other-client--per-operation-configuration>`_.
1741
+ #other-client--per-operation-configuration>`__.
1520
1742
  :returns: A BlobLeaseClient object.
1521
1743
  :rtype: ~azure.storage.blob.aio.BlobLeaseClient
1522
1744
 
@@ -1529,13 +1751,12 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1529
1751
  :dedent: 12
1530
1752
  :caption: Acquiring a lease on a blob.
1531
1753
  """
1532
- lease = BlobLeaseClient(self, lease_id=lease_id) # type: ignore
1754
+ lease = BlobLeaseClient(self, lease_id=lease_id)
1533
1755
  await lease.acquire(lease_duration=lease_duration, **kwargs)
1534
1756
  return lease
1535
1757
 
1536
1758
  @distributed_trace_async
1537
- async def set_standard_blob_tier(self, standard_blob_tier, **kwargs):
1538
- # type: (Union[str, StandardBlobTier], Any) -> None
1759
+ async def set_standard_blob_tier(self, standard_blob_tier: Union[str, "StandardBlobTier"], **kwargs: Any) -> None:
1539
1760
  """This operation sets the tier on a block blob.
1540
1761
 
1541
1762
  A block blob's tier determines Hot/Cool/Archive storage type.
@@ -1562,7 +1783,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1562
1783
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1563
1784
  This value is not tracked or validated on the client. To configure client-side network timesouts
1564
1785
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1565
- #other-client--per-operation-configuration>`_.
1786
+ #other-client--per-operation-configuration>`__.
1566
1787
  :keyword lease:
1567
1788
  Required if the blob has an active lease. Value can be a BlobLeaseClient object
1568
1789
  or the lease ID as a string.
@@ -1587,19 +1808,18 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1587
1808
 
1588
1809
  @distributed_trace_async
1589
1810
  async def stage_block(
1590
- self, block_id, # type: str
1591
- data, # type: Union[Iterable[AnyStr], IO[AnyStr]]
1592
- length=None, # type: Optional[int]
1593
- **kwargs
1594
- ):
1595
- # 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]:
1596
1816
  """Creates a new block to be committed as part of a blob.
1597
1817
 
1598
1818
  :param str block_id: A string value that identifies the block.
1599
1819
  The string should be less than or equal to 64 bytes in size.
1600
1820
  For a given blob, the block_id must be the same size for each block.
1601
1821
  :param data: The blob data.
1602
- :type data: Union[Iterable[AnyStr], IO[AnyStr]]
1822
+ :type data: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]]
1603
1823
  :param int length: Size of the block.
1604
1824
  :keyword bool validate_content:
1605
1825
  If true, calculates an MD5 hash for each chunk of the blob. The storage
@@ -1634,30 +1854,33 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1634
1854
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1635
1855
  This value is not tracked or validated on the client. To configure client-side network timesouts
1636
1856
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1637
- #other-client--per-operation-configuration>`_.
1857
+ #other-client--per-operation-configuration>`__.
1638
1858
  :returns: Blob property dict.
1639
1859
  :rtype: Dict[str, Any]
1640
1860
  """
1641
- options = self._stage_block_options(
1642
- block_id,
1643
- data,
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,
1644
1868
  length=length,
1645
1869
  **kwargs)
1646
1870
  try:
1647
- return await self._client.block_blob.stage_block(**options)
1871
+ return cast(Dict[str, Any], await self._client.block_blob.stage_block(**options))
1648
1872
  except HttpResponseError as error:
1649
1873
  process_storage_error(error)
1650
1874
 
1651
1875
  @distributed_trace_async
1652
1876
  async def stage_block_from_url(
1653
- self, block_id, # type: Union[str, int]
1654
- source_url, # type: str
1655
- source_offset=None, # type: Optional[int]
1656
- source_length=None, # type: Optional[int]
1657
- source_content_md5=None, # type: Optional[Union[bytes, bytearray]]
1658
- **kwargs
1659
- ):
1660
- # 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]:
1661
1884
  """Creates a new block to be committed as part of a blob where
1662
1885
  the contents are read from a URL.
1663
1886
 
@@ -1694,28 +1917,32 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1694
1917
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1695
1918
  This value is not tracked or validated on the client. To configure client-side network timesouts
1696
1919
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1697
- #other-client--per-operation-configuration>`_.
1920
+ #other-client--per-operation-configuration>`__.
1698
1921
  :keyword str source_authorization:
1699
1922
  Authenticate as a service principal using a client secret to access a source blob. Ensure "bearer " is
1700
1923
  the prefix of the source_authorization string.
1701
1924
  :returns: Blob property dict.
1702
1925
  :rtype: Dict[str, Any]
1703
1926
  """
1704
- options = self._stage_block_from_url_options(
1705
- block_id,
1706
- source_url=self._encode_source_url(source_url),
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,
1707
1932
  source_offset=source_offset,
1708
1933
  source_length=source_length,
1709
1934
  source_content_md5=source_content_md5,
1710
1935
  **kwargs)
1711
1936
  try:
1712
- 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))
1713
1938
  except HttpResponseError as error:
1714
1939
  process_storage_error(error)
1715
1940
 
1716
1941
  @distributed_trace_async
1717
- async def get_block_list(self, block_list_type="committed", **kwargs):
1718
- # type: (Optional[str], Any) -> Tuple[List[BlobBlock], List[BlobBlock]]
1942
+ async def get_block_list(
1943
+ self, block_list_type: str = "committed",
1944
+ **kwargs: Any
1945
+ ) -> Tuple[List[BlobBlock], List[BlobBlock]]:
1719
1946
  """The Get Block List operation retrieves the list of blocks that have
1720
1947
  been uploaded as part of a block blob.
1721
1948
 
@@ -1738,9 +1965,9 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1738
1965
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1739
1966
  This value is not tracked or validated on the client. To configure client-side network timesouts
1740
1967
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1741
- #other-client--per-operation-configuration>`_.
1968
+ #other-client--per-operation-configuration>`__.
1742
1969
  :returns: A tuple of two lists - committed and uncommitted blocks
1743
- :rtype: tuple(list(~azure.storage.blob.BlobBlock), list(~azure.storage.blob.BlobBlock))
1970
+ :rtype: Tuple[List[BlobBlock], List[BlobBlock]]
1744
1971
  """
1745
1972
  access_conditions = get_access_conditions(kwargs.pop('lease', None))
1746
1973
  mod_conditions = get_modify_conditions(kwargs)
@@ -1754,16 +1981,15 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1754
1981
  **kwargs)
1755
1982
  except HttpResponseError as error:
1756
1983
  process_storage_error(error)
1757
- return self._get_block_list_result(blocks)
1984
+ return _get_block_list_result(blocks)
1758
1985
 
1759
1986
  @distributed_trace_async
1760
- async def commit_block_list( # type: ignore
1761
- self, block_list, # type: List[BlobBlock]
1762
- content_settings=None, # type: Optional[ContentSettings]
1763
- metadata=None, # type: Optional[Dict[str, str]]
1764
- **kwargs
1765
- ):
1766
- # 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]]:
1767
1993
  """The Commit Block List operation writes a blob by specifying the list of
1768
1994
  block IDs that make up the blob.
1769
1995
 
@@ -1780,7 +2006,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1780
2006
  The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
1781
2007
  and tag values must be between 0 and 256 characters.
1782
2008
  Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
1783
- space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
2009
+ space (' '), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
1784
2010
 
1785
2011
  .. versionadded:: 12.4.0
1786
2012
 
@@ -1852,23 +2078,26 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1852
2078
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1853
2079
  This value is not tracked or validated on the client. To configure client-side network timesouts
1854
2080
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1855
- #other-client--per-operation-configuration>`_.
2081
+ #other-client--per-operation-configuration>`__.
1856
2082
  :returns: Blob-updated property dict (Etag and last modified).
1857
2083
  :rtype: dict(str, Any)
1858
2084
  """
1859
- options = self._commit_block_list_options(
1860
- block_list,
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,
1861
2091
  content_settings=content_settings,
1862
2092
  metadata=metadata,
1863
2093
  **kwargs)
1864
2094
  try:
1865
- return await self._client.block_blob.commit_block_list(**options) # type: ignore
2095
+ return cast(Dict[str, Any], await self._client.block_blob.commit_block_list(**options))
1866
2096
  except HttpResponseError as error:
1867
2097
  process_storage_error(error)
1868
2098
 
1869
2099
  @distributed_trace_async
1870
- async def set_premium_page_blob_tier(self, premium_page_blob_tier, **kwargs):
1871
- # type: (Union[str, PremiumPageBlobTier], **Any) -> None
2100
+ async def set_premium_page_blob_tier(self, premium_page_blob_tier: "PremiumPageBlobTier", **kwargs: Any) -> None:
1872
2101
  """Sets the page blob tiers on the blob. This API is only supported for page blobs on premium accounts.
1873
2102
 
1874
2103
  :param premium_page_blob_tier:
@@ -1887,7 +2116,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1887
2116
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1888
2117
  This value is not tracked or validated on the client. To configure client-side network timesouts
1889
2118
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1890
- #other-client--per-operation-configuration>`_.
2119
+ #other-client--per-operation-configuration>`__.
1891
2120
  :keyword lease:
1892
2121
  Required if the blob has an active lease. Value can be a BlobLeaseClient object
1893
2122
  or the lease ID as a string.
@@ -1909,8 +2138,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1909
2138
  process_storage_error(error)
1910
2139
 
1911
2140
  @distributed_trace_async
1912
- async def set_blob_tags(self, tags=None, **kwargs):
1913
- # 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]:
1914
2142
  """The Set Tags operation enables users to set tags on a blob or specific blob version, but not snapshot.
1915
2143
  Each call to this operation replaces all existing tags attached to the blob. To remove all
1916
2144
  tags from the blob, call this operation with no tags set.
@@ -1923,7 +2151,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1923
2151
  The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
1924
2152
  and tag values must be between 0 and 256 characters.
1925
2153
  Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
1926
- space (` `), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
2154
+ space (' '), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
1927
2155
  :type tags: dict(str, str)
1928
2156
  :keyword str version_id:
1929
2157
  The version id parameter is an opaque DateTime
@@ -1947,19 +2175,19 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1947
2175
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1948
2176
  This value is not tracked or validated on the client. To configure client-side network timesouts
1949
2177
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1950
- #other-client--per-operation-configuration>`_.
2178
+ #other-client--per-operation-configuration>`__.
1951
2179
  :returns: Blob-updated property dict (Etag and last modified)
1952
2180
  :rtype: Dict[str, Any]
1953
2181
  """
1954
- options = self._set_blob_tags_options(tags=tags, **kwargs)
2182
+ version_id = get_version_id(self.version_id, kwargs)
2183
+ options = _set_blob_tags_options(version_id=version_id, tags=tags, **kwargs)
1955
2184
  try:
1956
- return await self._client.blob.set_tags(**options)
2185
+ return cast(Dict[str, Any], await self._client.blob.set_tags(**options))
1957
2186
  except HttpResponseError as error:
1958
2187
  process_storage_error(error)
1959
2188
 
1960
2189
  @distributed_trace_async
1961
- async def get_blob_tags(self, **kwargs):
1962
- # type: (**Any) -> Dict[str, str]
2190
+ async def get_blob_tags(self, **kwargs: Any) -> Dict[str, str]:
1963
2191
  """The Get Tags operation enables users to get tags on a blob or specific blob version, but not snapshot.
1964
2192
 
1965
2193
  .. versionadded:: 12.4.0
@@ -1980,25 +2208,25 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
1980
2208
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
1981
2209
  This value is not tracked or validated on the client. To configure client-side network timesouts
1982
2210
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
1983
- #other-client--per-operation-configuration>`_.
2211
+ #other-client--per-operation-configuration>`__.
1984
2212
  :returns: Key value pairs of blob tags.
1985
2213
  :rtype: Dict[str, str]
1986
2214
  """
1987
- options = self._get_blob_tags_options(**kwargs)
2215
+ version_id = get_version_id(self.version_id, kwargs)
2216
+ options = _get_blob_tags_options(version_id=version_id, snapshot=self.snapshot, **kwargs)
1988
2217
  try:
1989
2218
  _, tags = await self._client.blob.get_tags(**options)
1990
- return parse_tags(tags) # pylint: disable=protected-access
2219
+ return cast(Dict[str, str], parse_tags(tags)) # pylint: disable=protected-access
1991
2220
  except HttpResponseError as error:
1992
2221
  process_storage_error(error)
1993
2222
 
1994
2223
  @distributed_trace_async
1995
- async def get_page_ranges( # type: ignore
1996
- self, offset=None, # type: Optional[int]
1997
- length=None, # type: Optional[int]
1998
- previous_snapshot_diff=None, # type: Optional[Union[str, Dict[str, Any]]]
1999
- **kwargs
2000
- ):
2001
- # 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]]]:
2002
2230
  """DEPRECATED: Returns the list of valid page ranges for a Page Blob or snapshot
2003
2231
  of a page blob.
2004
2232
 
@@ -2052,7 +2280,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2052
2280
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2053
2281
  This value is not tracked or validated on the client. To configure client-side network timesouts
2054
2282
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2055
- #other-client--per-operation-configuration>`_.
2283
+ #other-client--per-operation-configuration>`__.
2056
2284
  :returns:
2057
2285
  A tuple of two lists of page ranges as dictionaries with 'start' and 'end' keys.
2058
2286
  The first element are filled page ranges, the 2nd element is cleared page ranges.
@@ -2063,7 +2291,8 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2063
2291
  DeprecationWarning
2064
2292
  )
2065
2293
 
2066
- options = self._get_page_ranges_options(
2294
+ options = _get_page_ranges_options(
2295
+ snapshot=self.snapshot,
2067
2296
  offset=offset,
2068
2297
  length=length,
2069
2298
  previous_snapshot_diff=previous_snapshot_diff,
@@ -2079,13 +2308,13 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2079
2308
 
2080
2309
  @distributed_trace
2081
2310
  def list_page_ranges(
2082
- self,
2083
- *,
2084
- offset: Optional[int] = None,
2085
- length: Optional[int] = None,
2086
- previous_snapshot: Optional[Union[str, Dict[str, Any]]] = None,
2087
- **kwargs: Any
2088
- ) -> AsyncItemPaged[PageRange]:
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]:
2089
2318
  """Returns the list of valid page ranges for a Page Blob or snapshot
2090
2319
  of a page blob. If `previous_snapshot` is specified, the result will be
2091
2320
  a diff of changes between the target blob and the previous snapshot.
@@ -2144,12 +2373,13 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2144
2373
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2145
2374
  This value is not tracked or validated on the client. To configure client-side network timesouts
2146
2375
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2147
- #other-client--per-operation-configuration>`_.
2376
+ #other-client--per-operation-configuration>`__.
2148
2377
  :returns: An iterable (auto-paging) of PageRange.
2149
2378
  :rtype: ~azure.core.paging.ItemPaged[~azure.storage.blob.PageRange]
2150
2379
  """
2151
2380
  results_per_page = kwargs.pop('results_per_page', None)
2152
- options = self._get_page_ranges_options(
2381
+ options = _get_page_ranges_options(
2382
+ snapshot=self.snapshot,
2153
2383
  offset=offset,
2154
2384
  length=length,
2155
2385
  previous_snapshot_diff=previous_snapshot,
@@ -2169,12 +2399,11 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2169
2399
 
2170
2400
  @distributed_trace_async
2171
2401
  async def get_page_range_diff_for_managed_disk(
2172
- self, previous_snapshot_url, # type: str
2173
- offset=None, # type: Optional[int]
2174
- length=None, # type: Optional[int]
2175
- **kwargs
2176
- ):
2177
- # 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]]]:
2178
2407
  """Returns the list of valid page ranges for a managed disk or snapshot.
2179
2408
 
2180
2409
  .. note::
@@ -2227,13 +2456,14 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2227
2456
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2228
2457
  This value is not tracked or validated on the client. To configure client-side network timesouts
2229
2458
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2230
- #other-client--per-operation-configuration>`_.
2459
+ #other-client--per-operation-configuration>`__.
2231
2460
  :returns:
2232
2461
  A tuple of two lists of page ranges as dictionaries with 'start' and 'end' keys.
2233
2462
  The first element are filled page ranges, the 2nd element is cleared page ranges.
2234
2463
  :rtype: tuple(list(dict(str, str), list(dict(str, str))
2235
2464
  """
2236
- options = self._get_page_ranges_options(
2465
+ options = _get_page_ranges_options(
2466
+ snapshot=self.snapshot,
2237
2467
  offset=offset,
2238
2468
  length=length,
2239
2469
  prev_snapshot_url=previous_snapshot_url,
@@ -2245,12 +2475,11 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2245
2475
  return get_page_ranges_result(ranges)
2246
2476
 
2247
2477
  @distributed_trace_async
2248
- async def set_sequence_number( # type: ignore
2249
- self, sequence_number_action, # type: Union[str, SequenceNumberAction]
2250
- sequence_number=None, # type: Optional[str]
2251
- **kwargs
2252
- ):
2253
- # 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]]:
2254
2483
  """Sets the blob sequence number.
2255
2484
 
2256
2485
  :param str sequence_number_action:
@@ -2292,20 +2521,18 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2292
2521
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2293
2522
  This value is not tracked or validated on the client. To configure client-side network timesouts
2294
2523
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2295
- #other-client--per-operation-configuration>`_.
2524
+ #other-client--per-operation-configuration>`__.
2296
2525
  :returns: Blob-updated property dict (Etag and last modified).
2297
2526
  :rtype: dict(str, Any)
2298
2527
  """
2299
- options = self._set_sequence_number_options(
2300
- sequence_number_action, sequence_number=sequence_number, **kwargs)
2528
+ options = _set_sequence_number_options(sequence_number_action, sequence_number=sequence_number, **kwargs)
2301
2529
  try:
2302
- return await self._client.page_blob.update_sequence_number(**options) # type: ignore
2530
+ return cast(Dict[str, Any], await self._client.page_blob.update_sequence_number(**options))
2303
2531
  except HttpResponseError as error:
2304
2532
  process_storage_error(error)
2305
2533
 
2306
2534
  @distributed_trace_async
2307
- async def resize_blob(self, size, **kwargs):
2308
- # type: (int, Any) -> Dict[str, Union[str, datetime]]
2535
+ async def resize_blob(self, size: int, **kwargs: Any) -> Dict[str, Union[str, datetime]]:
2309
2536
  """Resizes a page blob to the specified size.
2310
2537
 
2311
2538
  If the specified value is less than the current size of the blob,
@@ -2350,24 +2577,25 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2350
2577
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2351
2578
  This value is not tracked or validated on the client. To configure client-side network timesouts
2352
2579
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2353
- #other-client--per-operation-configuration>`_.
2580
+ #other-client--per-operation-configuration>`__.
2354
2581
  :returns: Blob-updated property dict (Etag and last modified).
2355
2582
  :rtype: dict(str, Any)
2356
2583
  """
2357
- options = self._resize_blob_options(size, **kwargs)
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)
2358
2587
  try:
2359
- return await self._client.page_blob.resize(**options) # type: ignore
2588
+ return cast(Dict[str, Any], await self._client.page_blob.resize(**options))
2360
2589
  except HttpResponseError as error:
2361
2590
  process_storage_error(error)
2362
2591
 
2363
2592
  @distributed_trace_async
2364
- async def upload_page( # type: ignore
2365
- self, page, # type: bytes
2366
- offset, # type: int
2367
- length, # type: int
2368
- **kwargs
2369
- ):
2370
- # 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]]:
2371
2599
  """The Upload Pages operation writes a range of pages to a page blob.
2372
2600
 
2373
2601
  :param bytes page:
@@ -2445,28 +2673,32 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2445
2673
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2446
2674
  This value is not tracked or validated on the client. To configure client-side network timesouts
2447
2675
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2448
- #other-client--per-operation-configuration>`_.
2676
+ #other-client--per-operation-configuration>`__.
2449
2677
  :returns: Blob-updated property dict (Etag and last modified).
2450
2678
  :rtype: dict(str, Any)
2451
2679
  """
2452
- options = self._upload_page_options(
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(
2453
2685
  page=page,
2454
2686
  offset=offset,
2455
2687
  length=length,
2456
2688
  **kwargs)
2457
2689
  try:
2458
- return await self._client.page_blob.upload_pages(**options) # type: ignore
2690
+ return cast(Dict[str, Any], await self._client.page_blob.upload_pages(**options))
2459
2691
  except HttpResponseError as error:
2460
2692
  process_storage_error(error)
2461
2693
 
2462
2694
  @distributed_trace_async
2463
- async def upload_pages_from_url(self, source_url, # type: str
2464
- offset, # type: int
2465
- length, # type: int
2466
- source_offset, # type: int
2467
- **kwargs
2468
- ):
2469
- # type: (...) -> Dict[str, Any]
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]:
2470
2702
  """
2471
2703
  The Upload Pages operation writes a range of pages to a page blob where
2472
2704
  the contents are read from a URL.
@@ -2560,7 +2792,7 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2560
2792
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2561
2793
  This value is not tracked or validated on the client. To configure client-side network timesouts
2562
2794
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2563
- #other-client--per-operation-configuration>`_.
2795
+ #other-client--per-operation-configuration>`__.
2564
2796
  :keyword str source_authorization:
2565
2797
  Authenticate as a service principal using a client secret to access a source blob. Ensure "bearer " is
2566
2798
  the prefix of the source_authorization string.
@@ -2568,21 +2800,24 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2568
2800
  :rtype: Dict[str, Any]
2569
2801
  """
2570
2802
 
2571
- options = self._upload_pages_from_url_options(
2572
- source_url=self._encode_source_url(source_url),
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,
2573
2809
  offset=offset,
2574
2810
  length=length,
2575
2811
  source_offset=source_offset,
2576
2812
  **kwargs
2577
2813
  )
2578
2814
  try:
2579
- return await self._client.page_blob.upload_pages_from_url(**options) # type: ignore
2815
+ return cast(Dict[str, Any], await self._client.page_blob.upload_pages_from_url(**options))
2580
2816
  except HttpResponseError as error:
2581
2817
  process_storage_error(error)
2582
2818
 
2583
2819
  @distributed_trace_async
2584
- async def clear_page(self, offset, length, **kwargs):
2585
- # 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]]:
2586
2821
  """Clears a range of pages.
2587
2822
 
2588
2823
  :param int offset:
@@ -2641,23 +2876,30 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2641
2876
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2642
2877
  This value is not tracked or validated on the client. To configure client-side network timesouts
2643
2878
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2644
- #other-client--per-operation-configuration>`_.
2879
+ #other-client--per-operation-configuration>`__.
2645
2880
  :returns: Blob-updated property dict (Etag and last modified).
2646
2881
  :rtype: dict(str, Any)
2647
2882
  """
2648
- options = self._clear_page_options(offset, length, **kwargs)
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
+ )
2649
2892
  try:
2650
- return await self._client.page_blob.clear_pages(**options) # type: ignore
2893
+ return cast(Dict[str, Any], await self._client.page_blob.clear_pages(**options))
2651
2894
  except HttpResponseError as error:
2652
2895
  process_storage_error(error)
2653
2896
 
2654
2897
  @distributed_trace_async
2655
- async def append_block( # type: ignore
2656
- self, data, # type: Union[bytes, str, Iterable[AnyStr], IO[AnyStr]]
2657
- length=None, # type: Optional[int]
2658
- **kwargs
2659
- ):
2660
- # 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]]:
2661
2903
  """Commits a new block of data to the end of the existing append blob.
2662
2904
 
2663
2905
  :param data:
@@ -2731,26 +2973,31 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2731
2973
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2732
2974
  This value is not tracked or validated on the client. To configure client-side network timesouts
2733
2975
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2734
- #other-client--per-operation-configuration>`_.
2976
+ #other-client--per-operation-configuration>`__.
2735
2977
  :returns: Blob-updated property dict (Etag, last modified, append offset, committed block count).
2736
2978
  :rtype: dict(str, Any)
2737
2979
  """
2738
- options = self._append_block_options(
2739
- data,
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,
2740
2986
  length=length,
2741
2987
  **kwargs
2742
2988
  )
2743
2989
  try:
2744
- return await self._client.append_blob.append_block(**options) # type: ignore
2990
+ return cast(Dict[str, Any], await self._client.append_blob.append_block(**options))
2745
2991
  except HttpResponseError as error:
2746
2992
  process_storage_error(error)
2747
2993
 
2748
2994
  @distributed_trace_async
2749
- async def append_block_from_url(self, copy_source_url, # type: str
2750
- source_offset=None, # type: Optional[int]
2751
- source_length=None, # type: Optional[int]
2752
- **kwargs):
2753
- # type: (...) -> Dict[str, Union[str, datetime, int]]
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]]:
2754
3001
  """
2755
3002
  Creates a new block to be committed as part of a blob, where the contents are read from a source url.
2756
3003
 
@@ -2838,27 +3085,31 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2838
3085
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2839
3086
  This value is not tracked or validated on the client. To configure client-side network timesouts
2840
3087
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2841
- #other-client--per-operation-configuration>`_.
3088
+ #other-client--per-operation-configuration>`__.
2842
3089
  :keyword str source_authorization:
2843
3090
  Authenticate as a service principal using a client secret to access a source blob. Ensure "bearer " is
2844
3091
  the prefix of the source_authorization string.
2845
3092
  :returns: Result after appending a new block.
2846
3093
  :rtype: Dict[str, Union[str, datetime, int]]
2847
3094
  """
2848
- options = self._append_block_from_url_options(
2849
- copy_source_url=self._encode_source_url(copy_source_url),
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,
2850
3101
  source_offset=source_offset,
2851
3102
  source_length=source_length,
2852
3103
  **kwargs
2853
3104
  )
2854
3105
  try:
2855
- return await self._client.append_blob.append_block_from_url(**options) # type: ignore
3106
+ return cast(Dict[str, Union[str, datetime, int]],
3107
+ await self._client.append_blob.append_block_from_url(**options))
2856
3108
  except HttpResponseError as error:
2857
3109
  process_storage_error(error)
2858
3110
 
2859
3111
  @distributed_trace_async
2860
- async def seal_append_blob(self, **kwargs):
2861
- # type: (...) -> Dict[str, Union[str, datetime, int]]
3112
+ async def seal_append_blob(self, **kwargs: Any) -> Dict[str, Union[str, datetime, int]]:
2862
3113
  """The Seal operation seals the Append Blob to make it read-only.
2863
3114
 
2864
3115
  .. versionadded:: 12.4.0
@@ -2895,18 +3146,19 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2895
3146
  https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-blob-service-operations.
2896
3147
  This value is not tracked or validated on the client. To configure client-side network timesouts
2897
3148
  see `here <https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob
2898
- #other-client--per-operation-configuration>`_.
3149
+ #other-client--per-operation-configuration>`__.
2899
3150
  :returns: Blob-updated property dict (Etag, last modified, append offset, committed block count).
2900
3151
  :rtype: dict(str, Any)
2901
3152
  """
2902
- options = self._seal_append_blob_options(**kwargs)
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)
2903
3156
  try:
2904
- return await self._client.append_blob.seal(**options) # type: ignore
3157
+ return cast(Dict[str, Any], await self._client.append_blob.seal(**options))
2905
3158
  except HttpResponseError as error:
2906
3159
  process_storage_error(error)
2907
3160
 
2908
- def _get_container_client(self): # pylint: disable=client-method-missing-kwargs
2909
- # type: (...) -> ContainerClient
3161
+ def _get_container_client(self) -> "ContainerClient":
2910
3162
  """Get a client to interact with the blob's parent container.
2911
3163
 
2912
3164
  The container need not already exist. Defaults to current blob's credentials.
@@ -2927,7 +3179,8 @@ class BlobClient(AsyncStorageAccountHostsMixin, BlobClientBase, StorageEncryptio
2927
3179
  if not isinstance(self._pipeline._transport, AsyncTransportWrapper): # pylint: disable = protected-access
2928
3180
  _pipeline = AsyncPipeline(
2929
3181
  transport=AsyncTransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
2930
- policies=self._pipeline._impl_policies # pylint: disable = protected-access
3182
+ policies=cast(Iterable["AsyncHTTPPolicy"],
3183
+ self._pipeline._impl_policies) # pylint: disable = protected-access
2931
3184
  )
2932
3185
  else:
2933
3186
  _pipeline = self._pipeline # pylint: disable = protected-access