azure-storage-blob 12.21.0__py3-none-any.whl → 12.22.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. azure/storage/blob/__init__.py +19 -18
  2. azure/storage/blob/_blob_client.py +417 -1507
  3. azure/storage/blob/_blob_client_helpers.py +1242 -0
  4. azure/storage/blob/_blob_service_client.py +82 -101
  5. azure/storage/blob/_blob_service_client_helpers.py +27 -0
  6. azure/storage/blob/_container_client.py +147 -356
  7. azure/storage/blob/_container_client_helpers.py +261 -0
  8. azure/storage/blob/_deserialize.py +68 -44
  9. azure/storage/blob/_download.py +114 -90
  10. azure/storage/blob/_encryption.py +14 -7
  11. azure/storage/blob/_lease.py +47 -58
  12. azure/storage/blob/_list_blobs_helper.py +129 -135
  13. azure/storage/blob/_models.py +479 -276
  14. azure/storage/blob/_quick_query_helper.py +30 -31
  15. azure/storage/blob/_serialize.py +38 -56
  16. azure/storage/blob/_shared/avro/datafile.py +1 -1
  17. azure/storage/blob/_shared/avro/datafile_async.py +1 -1
  18. azure/storage/blob/_shared/base_client.py +1 -1
  19. azure/storage/blob/_shared/base_client_async.py +1 -1
  20. azure/storage/blob/_shared/policies.py +8 -6
  21. azure/storage/blob/_shared/policies_async.py +3 -1
  22. azure/storage/blob/_shared/response_handlers.py +6 -2
  23. azure/storage/blob/_shared/shared_access_signature.py +2 -2
  24. azure/storage/blob/_shared/uploads.py +1 -1
  25. azure/storage/blob/_shared/uploads_async.py +1 -1
  26. azure/storage/blob/_shared_access_signature.py +70 -53
  27. azure/storage/blob/_upload_helpers.py +75 -68
  28. azure/storage/blob/_version.py +1 -1
  29. azure/storage/blob/aio/__init__.py +19 -11
  30. azure/storage/blob/aio/_blob_client_async.py +505 -255
  31. azure/storage/blob/aio/_blob_service_client_async.py +138 -87
  32. azure/storage/blob/aio/_container_client_async.py +260 -120
  33. azure/storage/blob/aio/_download_async.py +104 -87
  34. azure/storage/blob/aio/_lease_async.py +56 -55
  35. azure/storage/blob/aio/_list_blobs_helper.py +94 -96
  36. azure/storage/blob/aio/_models.py +60 -38
  37. azure/storage/blob/aio/_upload_helpers.py +75 -66
  38. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/METADATA +1 -1
  39. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/RECORD +42 -39
  40. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/LICENSE +0 -0
  41. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/WHEEL +0 -0
  42. {azure_storage_blob-12.21.0.dist-info → azure_storage_blob-12.22.0.dist-info}/top_level.txt +0 -0
@@ -7,52 +7,62 @@
7
7
 
8
8
  import functools
9
9
  import warnings
10
- from typing import ( # pylint: disable=unused-import
11
- Any, AnyStr, AsyncIterable, AsyncIterator, Dict, List, IO, Iterable, Optional, overload, Union,
10
+ from datetime import datetime
11
+ from typing import (
12
+ Any, AnyStr, AsyncIterable, AsyncIterator, cast, Dict, List, IO, Iterable, Optional, overload, Union,
12
13
  TYPE_CHECKING
13
14
  )
15
+ from urllib.parse import unquote, urlparse
16
+ from typing_extensions import Self
14
17
 
15
- from azure.core.async_paging import AsyncItemPaged
18
+ from azure.core.async_paging import AsyncItemPaged, AsyncList
16
19
  from azure.core.exceptions import HttpResponseError, ResourceNotFoundError
17
20
  from azure.core.pipeline import AsyncPipeline
21
+ from azure.core.pipeline.transport import AsyncHttpResponse # pylint: disable=C4756
18
22
  from azure.core.tracing.decorator import distributed_trace
19
23
  from azure.core.tracing.decorator_async import distributed_trace_async
20
24
 
21
- from .._shared.base_client_async import AsyncStorageAccountHostsMixin, AsyncTransportWrapper
22
- from .._shared.policies_async import ExponentialRetry
23
- from .._shared.request_handlers import add_metadata_headers, serialize_iso
24
- from .._shared.response_handlers import (
25
- process_storage_error,
26
- return_response_headers,
27
- return_headers_and_deserialized
25
+ from ._blob_client_async import BlobClient
26
+ from ._download_async import StorageStreamDownloader
27
+ from ._lease_async import BlobLeaseClient
28
+ from ._list_blobs_helper import BlobNamesPaged, BlobPropertiesPaged, BlobPrefix
29
+ from ._models import FilteredBlobPaged
30
+ from .._container_client_helpers import (
31
+ _format_url,
32
+ _generate_delete_blobs_options,
33
+ _generate_set_tiers_options,
34
+ _parse_url
28
35
  )
29
- from .._generated.aio import AzureBlobStorage
30
- from .._generated.models import SignedIdentifier
31
- from .._container_client import ContainerClient as ContainerClientBase, _get_blob_name
32
36
  from .._deserialize import deserialize_container_properties
33
- from ._download_async import StorageStreamDownloader
34
37
  from .._encryption import StorageEncryptionMixin
38
+ from .._generated.aio import AzureBlobStorage
39
+ from .._generated.models import SignedIdentifier
40
+ from .._list_blobs_helper import IgnoreListBlobsDeserializer
35
41
  from .._models import ContainerProperties, BlobType, BlobProperties, FilteredBlob
36
42
  from .._serialize import get_modify_conditions, get_container_cpk_scope_info, get_api_version, get_access_conditions
37
- from ._blob_client_async import BlobClient
38
- from ._lease_async import BlobLeaseClient
39
- from ._list_blobs_helper import BlobNamesPaged, BlobPropertiesPaged, BlobPrefix
40
- from .._list_blobs_helper import IgnoreListBlobsDeserializer
41
- from ._models import FilteredBlobPaged
43
+ from .._shared.base_client import StorageAccountHostsMixin
44
+ from .._shared.base_client_async import AsyncStorageAccountHostsMixin, AsyncTransportWrapper, parse_connection_str
45
+ from .._shared.policies_async import ExponentialRetry
46
+ from .._shared.request_handlers import add_metadata_headers, serialize_iso
47
+ from .._shared.response_handlers import (
48
+ process_storage_error,
49
+ return_headers_and_deserialized,
50
+ return_response_headers
51
+ )
42
52
 
43
53
  if TYPE_CHECKING:
44
54
  from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential
45
55
  from azure.core.credentials_async import AsyncTokenCredential
46
- from azure.core.pipeline.transport import AsyncHttpResponse # pylint: disable=C4756
47
- from datetime import datetime
48
- from .._models import ( # pylint: disable=unused-import
56
+ from ._blob_service_client_async import BlobServiceClient
57
+ from .._models import (
49
58
  AccessPolicy,
50
59
  StandardBlobTier,
51
60
  PremiumPageBlobTier,
52
- PublicAccess)
61
+ PublicAccess
62
+ )
53
63
 
54
64
 
55
- class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, StorageEncryptionMixin):
65
+ class ContainerClient(AsyncStorageAccountHostsMixin, StorageAccountHostsMixin, StorageEncryptionMixin): # type: ignore [misc] # pylint: disable=too-many-public-methods
56
66
  """A client to interact with a specific container, although that container
57
67
  may not yet exist.
58
68
 
@@ -116,29 +126,143 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
116
126
  :caption: Creating the container client directly.
117
127
  """
118
128
  def __init__(
119
- self, account_url: str,
120
- container_name: str,
121
- credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long
122
- **kwargs: Any
123
- ) -> None:
129
+ self, account_url: str,
130
+ container_name: str,
131
+ credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long
132
+ **kwargs: Any
133
+ ) -> None:
124
134
  kwargs['retry_policy'] = kwargs.get('retry_policy') or ExponentialRetry(**kwargs)
125
- super(ContainerClient, self).__init__(
126
- account_url,
127
- container_name=container_name,
128
- credential=credential,
129
- **kwargs)
135
+ parsed_url, sas_token = _parse_url(account_url=account_url, container_name=container_name)
136
+
137
+ self.container_name = container_name
138
+ # This parameter is used for the hierarchy traversal. Give precedence to credential.
139
+ self._raw_credential = credential if credential else sas_token
140
+ self._query_str, credential = self._format_query_string(sas_token, credential)
141
+ super(ContainerClient, self).__init__(parsed_url, service='blob', credential=credential, **kwargs)
130
142
  self._api_version = get_api_version(kwargs)
131
143
  self._client = self._build_generated_client()
132
144
  self._configure_encryption(kwargs)
133
145
 
134
- def _build_generated_client(self):
146
+ def _build_generated_client(self) -> AzureBlobStorage:
135
147
  client = AzureBlobStorage(self.url, base_url=self.url, pipeline=self._pipeline)
136
- client._config.version = self._api_version # pylint: disable=protected-access
148
+ client._config.version = self._api_version # type: ignore [assignment] # pylint: disable=protected-access
137
149
  return client
138
150
 
151
+ def _format_url(self, hostname):
152
+ return _format_url(
153
+ container_name=self.container_name,
154
+ hostname=hostname,
155
+ scheme=self.scheme,
156
+ query_str=self._query_str
157
+ )
158
+
159
+ @classmethod
160
+ def from_container_url(
161
+ cls, container_url: str,
162
+ credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long
163
+ **kwargs: Any
164
+ ) -> Self:
165
+ """Create ContainerClient from a container url.
166
+
167
+ :param str container_url:
168
+ The full endpoint URL to the Container, including SAS token if used. This could be
169
+ either the primary endpoint, or the secondary endpoint depending on the current `location_mode`.
170
+ :type container_url: str
171
+ :param credential:
172
+ The credentials with which to authenticate. This is optional if the
173
+ account URL already has a SAS token, or the connection string already has shared
174
+ access key values. The value can be a SAS token string,
175
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
176
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
177
+ If the resource URI already contains a SAS token, this will be ignored in favor of an explicit credential
178
+ - except in the case of AzureSasCredential, where the conflicting SAS tokens will raise a ValueError.
179
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
180
+ should be the storage account key.
181
+ :type credential:
182
+ ~azure.core.credentials.AzureNamedKeyCredential or
183
+ ~azure.core.credentials.AzureSasCredential or
184
+ ~azure.core.credentials_async.AsyncTokenCredential or
185
+ str or dict[str, str] or None
186
+ :keyword str audience: The audience to use when requesting tokens for Azure Active Directory
187
+ authentication. Only has an effect when credential is of type TokenCredential. The value could be
188
+ https://storage.azure.com/ (default) or https://<account>.blob.core.windows.net.
189
+ :returns: A container client.
190
+ :rtype: ~azure.storage.blob.ContainerClient
191
+ """
192
+ try:
193
+ if not container_url.lower().startswith('http'):
194
+ container_url = "https://" + container_url
195
+ except AttributeError as exc:
196
+ raise ValueError("Container URL must be a string.") from exc
197
+ parsed_url = urlparse(container_url)
198
+ if not parsed_url.netloc:
199
+ raise ValueError(f"Invalid URL: {container_url}")
200
+
201
+ container_path = parsed_url.path.strip('/').split('/')
202
+ account_path = ""
203
+ if len(container_path) > 1:
204
+ account_path = "/" + "/".join(container_path[:-1])
205
+ account_url = f"{parsed_url.scheme}://{parsed_url.netloc.rstrip('/')}{account_path}?{parsed_url.query}"
206
+ container_name = unquote(container_path[-1])
207
+ if not container_name:
208
+ raise ValueError("Invalid URL. Please provide a URL with a valid container name")
209
+ return cls(account_url, container_name=container_name, credential=credential, **kwargs)
210
+
211
+ @classmethod
212
+ def from_connection_string(
213
+ cls, conn_str: str,
214
+ container_name: str,
215
+ credential: Optional[Union[str, Dict[str, str], "AzureNamedKeyCredential", "AzureSasCredential", "AsyncTokenCredential"]] = None, # pylint: disable=line-too-long
216
+ **kwargs: Any
217
+ ) -> Self:
218
+ """Create ContainerClient from a Connection String.
219
+
220
+ :param str conn_str:
221
+ A connection string to an Azure Storage account.
222
+ :param container_name:
223
+ The container name for the blob.
224
+ :type container_name: str
225
+ :param credential:
226
+ The credentials with which to authenticate. This is optional if the
227
+ account URL already has a SAS token, or the connection string already has shared
228
+ access key values. The value can be a SAS token string,
229
+ an instance of a AzureSasCredential or AzureNamedKeyCredential from azure.core.credentials,
230
+ an account shared access key, or an instance of a TokenCredentials class from azure.identity.
231
+ Credentials provided here will take precedence over those in the connection string.
232
+ If using an instance of AzureNamedKeyCredential, "name" should be the storage account name, and "key"
233
+ should be the storage account key.
234
+ :type credential:
235
+ ~azure.core.credentials.AzureNamedKeyCredential or
236
+ ~azure.core.credentials.AzureSasCredential or
237
+ ~azure.core.credentials_async.AsyncTokenCredential or
238
+ str or dict[str, str] or None
239
+ :keyword str audience: The audience to use when requesting tokens for Azure Active Directory
240
+ authentication. Only has an effect when credential is of type TokenCredential. The value could be
241
+ https://storage.azure.com/ (default) or https://<account>.blob.core.windows.net.
242
+ :returns: A container client.
243
+ :rtype: ~azure.storage.blob.ContainerClient
244
+
245
+ .. admonition:: Example:
246
+
247
+ .. literalinclude:: ../samples/blob_samples_authentication.py
248
+ :start-after: [START auth_from_connection_string_container]
249
+ :end-before: [END auth_from_connection_string_container]
250
+ :language: python
251
+ :dedent: 8
252
+ :caption: Creating the ContainerClient from a connection string.
253
+ """
254
+ account_url, secondary, credential = parse_connection_str(conn_str, credential, 'blob')
255
+ if 'secondary_hostname' not in kwargs:
256
+ kwargs['secondary_hostname'] = secondary
257
+ return cls(
258
+ account_url, container_name=container_name, credential=credential, **kwargs)
259
+
139
260
  @distributed_trace_async
140
- async def create_container(self, metadata=None, public_access=None, **kwargs):
141
- # type: (Optional[Dict[str, str]], Optional[Union[PublicAccess, str]], **Any) -> Dict[str, Union[str, datetime]]
261
+ async def create_container(
262
+ self, metadata: Optional[Dict[str, str]] = None,
263
+ public_access: Optional[Union["PublicAccess", str]] = None,
264
+ **kwargs: Any
265
+ ) -> Dict[str, Union[str, datetime]]:
142
266
  """
143
267
  Creates a new container under the specified account. If the container
144
268
  with the same name already exists, the operation fails.
@@ -190,8 +314,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
190
314
  process_storage_error(error)
191
315
 
192
316
  @distributed_trace_async
193
- async def _rename_container(self, new_name, **kwargs):
194
- # type: (str, **Any) -> ContainerClient
317
+ async def _rename_container(self, new_name: str, **kwargs: Any) -> "ContainerClient":
195
318
  """Renames a container.
196
319
 
197
320
  Operation is successful only if the source container exists.
@@ -229,9 +352,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
229
352
  process_storage_error(error)
230
353
 
231
354
  @distributed_trace_async
232
- async def delete_container(
233
- self, **kwargs):
234
- # type: (Any) -> None
355
+ async def delete_container(self, **kwargs: Any) -> None:
235
356
  """
236
357
  Marks the specified container for deletion. The container and any blobs
237
358
  contained within it are later deleted during garbage collection.
@@ -290,10 +411,10 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
290
411
 
291
412
  @distributed_trace_async
292
413
  async def acquire_lease(
293
- self, lease_duration=-1, # type: int
294
- lease_id=None, # type: Optional[str]
295
- **kwargs):
296
- # type: (...) -> BlobLeaseClient
414
+ self, lease_duration: int =-1,
415
+ lease_id: Optional[str] = None,
416
+ **kwargs: Any
417
+ ) -> BlobLeaseClient:
297
418
  """
298
419
  Requests a new lease. If the container does not have an active lease,
299
420
  the Blob service creates a lease on the container and returns a new
@@ -349,8 +470,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
349
470
  return lease
350
471
 
351
472
  @distributed_trace_async
352
- async def get_account_information(self, **kwargs):
353
- # type: (**Any) -> Dict[str, str]
473
+ async def get_account_information(self, **kwargs: Any) -> Dict[str, str]:
354
474
  """Gets information related to the storage account.
355
475
 
356
476
  The information can also be retrieved if the user has a SAS to a container or blob.
@@ -365,8 +485,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
365
485
  process_storage_error(error)
366
486
 
367
487
  @distributed_trace_async
368
- async def get_container_properties(self, **kwargs):
369
- # type: (**Any) -> ContainerProperties
488
+ async def get_container_properties(self, **kwargs: Any) -> ContainerProperties:
370
489
  """Returns all user-defined metadata and system properties for the specified
371
490
  container. The data returned does not include the container's list of blobs.
372
491
 
@@ -407,8 +526,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
407
526
  return response # type: ignore
408
527
 
409
528
  @distributed_trace_async
410
- async def exists(self, **kwargs):
411
- # type: (**Any) -> bool
529
+ async def exists(self, **kwargs: Any) -> bool:
412
530
  """
413
531
  Returns True if a container exists and returns False otherwise.
414
532
 
@@ -431,11 +549,10 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
431
549
  return False
432
550
 
433
551
  @distributed_trace_async
434
- async def set_container_metadata( # type: ignore
435
- self, metadata=None, # type: Optional[Dict[str, str]]
436
- **kwargs
437
- ):
438
- # type: (...) -> Dict[str, Union[str, datetime]]
552
+ async def set_container_metadata(
553
+ self, metadata: Optional[Dict[str, str]] = None,
554
+ **kwargs: Any
555
+ ) -> Dict[str, Union[str, datetime]]:
439
556
  """Sets one or more user-defined name-value pairs for the specified
440
557
  container. Each call to this operation replaces all existing metadata
441
558
  attached to the container. To remove all metadata from the container,
@@ -491,8 +608,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
491
608
  process_storage_error(error)
492
609
 
493
610
  @distributed_trace
494
- def _get_blob_service_client(self): # pylint: disable=client-method-missing-kwargs
495
- # type: (...) -> BlobServiceClient
611
+ def _get_blob_service_client(self) -> "BlobServiceClient": # pylint: disable=client-method-missing-kwargs
496
612
  """Get a client to interact with the container's parent service account.
497
613
 
498
614
  Defaults to current container's credentials.
@@ -513,7 +629,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
513
629
  if not isinstance(self._pipeline._transport, AsyncTransportWrapper): # pylint: disable = protected-access
514
630
  _pipeline = AsyncPipeline(
515
631
  transport=AsyncTransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
516
- policies=self._pipeline._impl_policies # pylint: disable = protected-access
632
+ policies=self._pipeline._impl_policies #type: ignore [arg-type] # pylint: disable = protected-access
517
633
  )
518
634
  else:
519
635
  _pipeline = self._pipeline # pylint: disable = protected-access
@@ -526,8 +642,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
526
642
 
527
643
 
528
644
  @distributed_trace_async
529
- async def get_container_access_policy(self, **kwargs):
530
- # type: (Any) -> Dict[str, Any]
645
+ async def get_container_access_policy(self, **kwargs: Any) -> Dict[str, Any]:
531
646
  """Gets the permissions for the specified container.
532
647
  The permissions indicate whether container data may be accessed publicly.
533
648
 
@@ -571,10 +686,10 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
571
686
 
572
687
  @distributed_trace_async
573
688
  async def set_container_access_policy(
574
- self, signed_identifiers, # type: Dict[str, AccessPolicy]
575
- public_access=None, # type: Optional[Union[str, PublicAccess]]
576
- **kwargs # type: Any
577
- ): # type: (...) -> Dict[str, Union[str, datetime]]
689
+ self, signed_identifiers: Dict[str, "AccessPolicy"],
690
+ public_access: Optional[Union[str, "PublicAccess"]] = None,
691
+ **kwargs: Any
692
+ ) -> Dict[str, Union[str, datetime]]:
578
693
  """Sets the permissions for the specified container or stored access
579
694
  policies that may be used with Shared Access Signatures. The permissions
580
695
  indicate whether blobs in a container may be accessed publicly.
@@ -637,14 +752,14 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
637
752
  mod_conditions = get_modify_conditions(kwargs)
638
753
  access_conditions = get_access_conditions(lease)
639
754
  try:
640
- return await self._client.container.set_access_policy(
755
+ return cast(Dict[str, Union[str, datetime]], await self._client.container.set_access_policy(
641
756
  container_acl=signed_identifiers or None,
642
757
  timeout=timeout,
643
758
  access=public_access,
644
759
  lease_access_conditions=access_conditions,
645
760
  modified_access_conditions=mod_conditions,
646
761
  cls=return_response_headers,
647
- **kwargs)
762
+ **kwargs))
648
763
  except HttpResponseError as error:
649
764
  process_storage_error(error)
650
765
 
@@ -702,6 +817,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
702
817
  command,
703
818
  prefix=name_starts_with,
704
819
  results_per_page=results_per_page,
820
+ container=self.container_name,
705
821
  page_iterator_class=BlobPropertiesPaged
706
822
  )
707
823
 
@@ -748,6 +864,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
748
864
  command,
749
865
  prefix=name_starts_with,
750
866
  results_per_page=results_per_page,
867
+ container=self.container_name,
751
868
  page_iterator_class=BlobNamesPaged)
752
869
 
753
870
  @distributed_trace
@@ -756,7 +873,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
756
873
  include: Optional[Union[List[str], str]] = None,
757
874
  delimiter: str = "/",
758
875
  **kwargs: Any
759
- ) -> AsyncItemPaged[BlobProperties]:
876
+ ) -> AsyncItemPaged[BlobProperties]:
760
877
  """Returns a generator to list the blobs under the specified container.
761
878
  The generator will lazily follow the continuation tokens returned by
762
879
  the service. This operation will list blobs in accordance with a hierarchy,
@@ -803,14 +920,14 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
803
920
  command,
804
921
  prefix=name_starts_with,
805
922
  results_per_page=results_per_page,
923
+ container=self.container_name,
806
924
  delimiter=delimiter)
807
925
 
808
926
  @distributed_trace
809
927
  def find_blobs_by_tags(
810
- self, filter_expression, # type: str
811
- **kwargs # type: Optional[Any]
812
- ):
813
- # type: (...) -> AsyncItemPaged[FilteredBlob]
928
+ self, filter_expression: str,
929
+ **kwargs: Any
930
+ ) -> AsyncItemPaged[FilteredBlob]:
814
931
  """Returns a generator to list the blobs under the specified container whose tags
815
932
  match the given search expression.
816
933
  The generator will lazily follow the continuation tokens returned by
@@ -839,17 +956,18 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
839
956
  **kwargs)
840
957
  return AsyncItemPaged(
841
958
  command, results_per_page=results_per_page,
959
+ container=self.container_name,
842
960
  page_iterator_class=FilteredBlobPaged)
843
961
 
844
962
  @distributed_trace_async
845
963
  async def upload_blob(
846
- self, name: str,
847
- data: Union[bytes, str, Iterable[AnyStr], AsyncIterable[AnyStr], IO[AnyStr]],
848
- blob_type: Union[str, BlobType] = BlobType.BlockBlob,
849
- length: Optional[int] = None,
850
- metadata: Optional[Dict[str, str]] = None,
851
- **kwargs
852
- ) -> BlobClient:
964
+ self, name: str,
965
+ data: Union[bytes, str, Iterable[AnyStr], AsyncIterable[AnyStr], IO[AnyStr]],
966
+ blob_type: Union[str, BlobType] = BlobType.BLOCKBLOB,
967
+ length: Optional[int] = None,
968
+ metadata: Optional[Dict[str, str]] = None,
969
+ **kwargs
970
+ ) -> BlobClient:
853
971
  """Creates a new blob from a data source with automatic chunking.
854
972
 
855
973
  :param str name: The blob with which to interact.
@@ -988,9 +1106,9 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
988
1106
 
989
1107
  @distributed_trace_async
990
1108
  async def delete_blob(
991
- self, blob: str,
992
- delete_snapshots: Optional[str] = None,
993
- **kwargs: Any
1109
+ self, blob: str,
1110
+ delete_snapshots: Optional[str] = None,
1111
+ **kwargs: Any
994
1112
  ) -> None:
995
1113
  """Marks the specified blob or snapshot for deletion.
996
1114
 
@@ -1069,35 +1187,35 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
1069
1187
 
1070
1188
  @overload
1071
1189
  async def download_blob(
1072
- self, blob: str,
1073
- offset: int = None,
1074
- length: int = None,
1075
- *,
1076
- encoding: str,
1077
- **kwargs: Any
1190
+ self, blob: str,
1191
+ offset: Optional[int] = None,
1192
+ length: Optional[int] = None,
1193
+ *,
1194
+ encoding: str,
1195
+ **kwargs: Any
1078
1196
  ) -> StorageStreamDownloader[str]:
1079
1197
  ...
1080
1198
 
1081
1199
  @overload
1082
1200
  async def download_blob(
1083
- self, blob: str,
1084
- offset: int = None,
1085
- length: int = None,
1086
- *,
1087
- encoding: None = None,
1088
- **kwargs: Any
1201
+ self, blob: str,
1202
+ offset: Optional[int] = None,
1203
+ length: Optional[int] = None,
1204
+ *,
1205
+ encoding: None = None,
1206
+ **kwargs: Any
1089
1207
  ) -> StorageStreamDownloader[bytes]:
1090
1208
  ...
1091
1209
 
1092
1210
  @distributed_trace_async
1093
1211
  async def download_blob(
1094
- self, blob: str,
1095
- offset: int = None,
1096
- length: int = None,
1097
- *,
1098
- encoding: Optional[str] = None,
1099
- **kwargs: Any
1100
- ) -> StorageStreamDownloader:
1212
+ self, blob: str,
1213
+ offset: Optional[int] = None,
1214
+ length: Optional[int] = None,
1215
+ *,
1216
+ encoding: Union[str, None] = None,
1217
+ **kwargs: Any
1218
+ ) -> Union[StorageStreamDownloader[str], StorageStreamDownloader[bytes]]:
1101
1219
  """Downloads a blob to the StorageStreamDownloader. The readall() method must
1102
1220
  be used to read all the content or readinto() must be used to download the blob into
1103
1221
  a stream. Using chunks() returns an async iterator which allows the user to iterate over the content in chunks.
@@ -1198,7 +1316,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
1198
1316
  async def delete_blobs(
1199
1317
  self, *blobs: Union[str, Dict[str, Any], BlobProperties],
1200
1318
  **kwargs: Any
1201
- ) -> AsyncIterator["AsyncHttpResponse"]:
1319
+ ) -> AsyncIterator[AsyncHttpResponse]:
1202
1320
  """Marks the specified blobs or snapshots for deletion.
1203
1321
 
1204
1322
  The blobs are later deleted during garbage collection.
@@ -1224,6 +1342,8 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
1224
1342
  key: 'name', value type: str
1225
1343
  snapshot you want to delete:
1226
1344
  key: 'snapshot', value type: str
1345
+ version id:
1346
+ key: 'version_id', value type: str
1227
1347
  whether to delete snapshots when deleting blob:
1228
1348
  key: 'delete_snapshots', value: 'include' or 'only'
1229
1349
  if the blob modified or not:
@@ -1239,7 +1359,7 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
1239
1359
  timeout for subrequest:
1240
1360
  key: 'timeout', value type: int
1241
1361
 
1242
- :type blobs: str or dict(str, Any) or ~azure.storage.blob.BlobProperties
1362
+ :type blobs: Union[str, Dict[str, Any], BlobProperties]
1243
1363
  :keyword str delete_snapshots:
1244
1364
  Required if a blob has associated snapshots. Values include:
1245
1365
  - "only": Deletes only the blobs snapshots.
@@ -1285,18 +1405,24 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
1285
1405
  :caption: Deleting multiple blobs.
1286
1406
  """
1287
1407
  if len(blobs) == 0:
1288
- return iter([])
1408
+ return AsyncList([])
1289
1409
 
1290
- reqs, options = self._generate_delete_blobs_options(*blobs, **kwargs)
1410
+ reqs, options = _generate_delete_blobs_options(
1411
+ self._query_str,
1412
+ self.container_name,
1413
+ self._client,
1414
+ *blobs,
1415
+ **kwargs
1416
+ )
1291
1417
 
1292
- return await self._batch_send(*reqs, **options)
1418
+ return cast(AsyncIterator[AsyncHttpResponse], await self._batch_send(*reqs, **options))
1293
1419
 
1294
1420
  @distributed_trace_async
1295
1421
  async def set_standard_blob_tier_blobs(
1296
1422
  self, standard_blob_tier: Union[str, 'StandardBlobTier'],
1297
1423
  *blobs: Union[str, Dict[str, Any], BlobProperties],
1298
1424
  **kwargs: Any
1299
- ) -> AsyncIterator["AsyncHttpResponse"]:
1425
+ ) -> AsyncIterator[AsyncHttpResponse]:
1300
1426
  """This operation sets the tier on block blobs.
1301
1427
 
1302
1428
  A block blob's tier determines Hot/Cool/Archive storage type.
@@ -1359,16 +1485,22 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
1359
1485
  :return: An async iterator of responses, one for each blob in order
1360
1486
  :rtype: asynciterator[~azure.core.pipeline.transport.AsyncHttpResponse]
1361
1487
  """
1362
- reqs, options = self._generate_set_tiers_options(standard_blob_tier, *blobs, **kwargs)
1488
+ reqs, options = _generate_set_tiers_options(
1489
+ self._query_str,
1490
+ self.container_name,
1491
+ standard_blob_tier,
1492
+ self._client,
1493
+ *blobs,
1494
+ **kwargs)
1363
1495
 
1364
- return await self._batch_send(*reqs, **options)
1496
+ return cast(AsyncIterator[AsyncHttpResponse], await self._batch_send(*reqs, **options))
1365
1497
 
1366
1498
  @distributed_trace_async
1367
1499
  async def set_premium_page_blob_tier_blobs(
1368
1500
  self, premium_page_blob_tier: Union[str, 'PremiumPageBlobTier'],
1369
1501
  *blobs: Union[str, Dict[str, Any], BlobProperties],
1370
1502
  **kwargs: Any
1371
- ) -> AsyncIterator["AsyncHttpResponse"]:
1503
+ ) -> AsyncIterator[AsyncHttpResponse]:
1372
1504
  """Sets the page blob tiers on the blobs. This API is only supported for page blobs on premium accounts.
1373
1505
 
1374
1506
  The maximum number of blobs that can be updated in a single request is 256.
@@ -1412,15 +1544,21 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
1412
1544
  :return: An async iterator of responses, one for each blob in order
1413
1545
  :rtype: asynciterator[~azure.core.pipeline.transport.AsyncHttpResponse]
1414
1546
  """
1415
- reqs, options = self._generate_set_tiers_options(premium_page_blob_tier, *blobs, **kwargs)
1547
+ reqs, options = _generate_set_tiers_options(
1548
+ self._query_str,
1549
+ self.container_name,
1550
+ premium_page_blob_tier,
1551
+ self._client,
1552
+ *blobs,
1553
+ **kwargs)
1416
1554
 
1417
- return await self._batch_send(*reqs, **options)
1555
+ return cast(AsyncIterator[AsyncHttpResponse], await self._batch_send(*reqs, **options))
1418
1556
 
1419
1557
  def get_blob_client(
1420
- self, blob: str,
1421
- snapshot: str = None,
1422
- *,
1423
- version_id: Optional[str] = None
1558
+ self, blob: str,
1559
+ snapshot: Optional[str] = None,
1560
+ *,
1561
+ version_id: Optional[str] = None
1424
1562
  ) -> BlobClient:
1425
1563
  """Get a client to interact with the specified blob.
1426
1564
 
@@ -1451,10 +1589,12 @@ class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase, Storag
1451
1589
  "Please use 'BlobProperties.name' or any other str input type instead.",
1452
1590
  DeprecationWarning
1453
1591
  )
1454
- blob_name = _get_blob_name(blob)
1592
+ blob_name = blob.get('name')
1593
+ else:
1594
+ blob_name = blob
1455
1595
  _pipeline = AsyncPipeline(
1456
1596
  transport=AsyncTransportWrapper(self._pipeline._transport), # pylint: disable = protected-access
1457
- policies=self._pipeline._impl_policies # pylint: disable = protected-access
1597
+ policies=self._pipeline._impl_policies # type: ignore [arg-type] # pylint: disable = protected-access
1458
1598
  )
1459
1599
  return BlobClient(
1460
1600
  self.url, container_name=self.container_name, blob_name=blob_name, snapshot=snapshot,