1# pylint: disable=too-many-lines 2# ------------------------------------------------------------------------- 3# Copyright (c) Microsoft Corporation. All rights reserved. 4# Licensed under the MIT License. See License.txt in the project root for 5# license information. 6# -------------------------------------------------------------------------- 7 8import functools 9from typing import ( # pylint: disable=unused-import 10 Union, Optional, Any, Iterable, AnyStr, Dict, List, Tuple, IO, AsyncIterator, 11 TYPE_CHECKING 12) 13 14from azure.core.tracing.decorator import distributed_trace 15from azure.core.tracing.decorator_async import distributed_trace_async 16from azure.core.async_paging import AsyncItemPaged 17from azure.core.pipeline import AsyncPipeline 18from azure.core.pipeline.transport import HttpRequest, AsyncHttpResponse 19 20from .._shared.base_client_async import AsyncStorageAccountHostsMixin, AsyncTransportWrapper 21from .._shared.policies_async import ExponentialRetry 22from .._shared.request_handlers import add_metadata_headers, serialize_iso 23from .._shared.response_handlers import ( 24 process_storage_error, 25 return_response_headers, 26 return_headers_and_deserialized) 27from .._generated.aio import AzureBlobStorage 28from .._generated.models import ( 29 StorageErrorException, 30 SignedIdentifier) 31from .._deserialize import deserialize_container_properties 32from .._serialize import get_modify_conditions 33from .._container_client import ContainerClient as ContainerClientBase, _get_blob_name 34from .._lease import get_access_conditions 35from .._models import ContainerProperties, BlobProperties, BlobType # pylint: disable=unused-import 36from ._models import BlobPropertiesPaged, BlobPrefix 37from ._lease_async import BlobLeaseClient 38from ._blob_client_async import BlobClient 39 40if TYPE_CHECKING: 41 from azure.core.pipeline.transport import HttpTransport 42 from azure.core.pipeline.policies import HTTPPolicy 43 from .._models import ContainerSasPermissions, PublicAccess 44 from datetime import datetime 45 from .._models import ( # pylint: disable=unused-import 46 AccessPolicy, 47 ContentSettings, 48 StandardBlobTier, 49 PremiumPageBlobTier) 50 51 52class ContainerClient(AsyncStorageAccountHostsMixin, ContainerClientBase): 53 """A client to interact with a specific container, although that container 54 may not yet exist. 55 56 For operations relating to a specific blob within this container, a blob client can be 57 retrieved using the :func:`~get_blob_client` function. 58 59 :param str account_url: 60 The URI to the storage account. In order to create a client given the full URI to the container, 61 use the :func:`from_container_url` classmethod. 62 :param container_name: 63 The name of the container for the blob. 64 :type container_name: str 65 :param credential: 66 The credentials with which to authenticate. This is optional if the 67 account URL already has a SAS token. The value can be a SAS token string, an account 68 shared access key, or an instance of a TokenCredentials class from azure.identity. 69 If the URL already has a SAS token, specifying an explicit credential will take priority. 70 :keyword str secondary_hostname: 71 The hostname of the secondary endpoint. 72 :keyword int max_block_size: The maximum chunk size for uploading a block blob in chunks. 73 Defaults to 4*1024*1024, or 4MB. 74 :keyword int max_single_put_size: If the blob size is less than max_single_put_size, then the blob will be 75 uploaded with only one http PUT request. If the blob size is larger than max_single_put_size, 76 the blob will be uploaded in chunks. Defaults to 64*1024*1024, or 64MB. 77 :keyword int min_large_block_upload_threshold: The minimum chunk size required to use the memory efficient 78 algorithm when uploading a block blob. Defaults to 4*1024*1024+1. 79 :keyword bool use_byte_buffer: Use a byte buffer for block blob uploads. Defaults to False. 80 :keyword int max_page_size: The maximum chunk size for uploading a page blob. Defaults to 4*1024*1024, or 4MB. 81 :keyword int max_single_get_size: The maximum size for a blob to be downloaded in a single call, 82 the exceeded part will be downloaded in chunks (could be parallel). Defaults to 32*1024*1024, or 32MB. 83 :keyword int max_chunk_get_size: The maximum chunk size used for downloading a blob. Defaults to 4*1024*1024, 84 or 4MB. 85 86 .. admonition:: Example: 87 88 .. literalinclude:: ../samples/blob_samples_containers_async.py 89 :start-after: [START create_container_client_from_service] 90 :end-before: [END create_container_client_from_service] 91 :language: python 92 :dedent: 8 93 :caption: Get a ContainerClient from an existing BlobServiceClient. 94 95 .. literalinclude:: ../samples/blob_samples_containers_async.py 96 :start-after: [START create_container_client_sasurl] 97 :end-before: [END create_container_client_sasurl] 98 :language: python 99 :dedent: 12 100 :caption: Creating the container client directly. 101 """ 102 def __init__( 103 self, account_url, # type: str 104 container_name, # type: str 105 credential=None, # type: Optional[Any] 106 **kwargs # type: Any 107 ): 108 # type: (...) -> None 109 kwargs['retry_policy'] = kwargs.get('retry_policy') or ExponentialRetry(**kwargs) 110 super(ContainerClient, self).__init__( 111 account_url, 112 container_name=container_name, 113 credential=credential, 114 **kwargs) 115 self._client = AzureBlobStorage(url=self.url, pipeline=self._pipeline) 116 self._loop = kwargs.get('loop', None) 117 118 @distributed_trace_async 119 async def create_container(self, metadata=None, public_access=None, **kwargs): 120 # type: (Optional[Dict[str, str]], Optional[Union[PublicAccess, str]], **Any) -> None 121 """ 122 Creates a new container under the specified account. If the container 123 with the same name already exists, the operation fails. 124 125 :param metadata: 126 A dict with name_value pairs to associate with the 127 container as metadata. Example:{'Category':'test'} 128 :type metadata: dict[str, str] 129 :param ~azure.storage.blob.PublicAccess public_access: 130 Possible values include: 'container', 'blob'. 131 :keyword int timeout: 132 The timeout parameter is expressed in seconds. 133 :rtype: None 134 135 .. admonition:: Example: 136 137 .. literalinclude:: ../samples/blob_samples_containers_async.py 138 :start-after: [START create_container] 139 :end-before: [END create_container] 140 :language: python 141 :dedent: 16 142 :caption: Creating a container to store blobs. 143 """ 144 headers = kwargs.pop('headers', {}) 145 headers.update(add_metadata_headers(metadata)) # type: ignore 146 timeout = kwargs.pop('timeout', None) 147 try: 148 return await self._client.container.create( # type: ignore 149 timeout=timeout, 150 access=public_access, 151 cls=return_response_headers, 152 headers=headers, 153 **kwargs) 154 except StorageErrorException as error: 155 process_storage_error(error) 156 157 @distributed_trace_async 158 async def delete_container( 159 self, **kwargs): 160 # type: (Any) -> None 161 """ 162 Marks the specified container for deletion. The container and any blobs 163 contained within it are later deleted during garbage collection. 164 165 :keyword lease: 166 If specified, delete_container only succeeds if the 167 container's lease is active and matches this ID. 168 Required if the container has an active lease. 169 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 170 :keyword ~datetime.datetime if_modified_since: 171 A DateTime value. Azure expects the date value passed in to be UTC. 172 If timezone is included, any non-UTC datetimes will be converted to UTC. 173 If a date is passed in without timezone info, it is assumed to be UTC. 174 Specify this header to perform the operation only 175 if the resource has been modified since the specified time. 176 :keyword ~datetime.datetime if_unmodified_since: 177 A DateTime value. Azure expects the date value passed in to be UTC. 178 If timezone is included, any non-UTC datetimes will be converted to UTC. 179 If a date is passed in without timezone info, it is assumed to be UTC. 180 Specify this header to perform the operation only if 181 the resource has not been modified since the specified date/time. 182 :keyword str etag: 183 An ETag value, or the wildcard character (*). Used to check if the resource has changed, 184 and act according to the condition specified by the `match_condition` parameter. 185 :keyword ~azure.core.MatchConditions match_condition: 186 The match condition to use upon the etag. 187 :keyword int timeout: 188 The timeout parameter is expressed in seconds. 189 :rtype: None 190 191 .. admonition:: Example: 192 193 .. literalinclude:: ../samples/blob_samples_containers_async.py 194 :start-after: [START delete_container] 195 :end-before: [END delete_container] 196 :language: python 197 :dedent: 16 198 :caption: Delete a container. 199 """ 200 lease = kwargs.pop('lease', None) 201 access_conditions = get_access_conditions(lease) 202 mod_conditions = get_modify_conditions(kwargs) 203 timeout = kwargs.pop('timeout', None) 204 try: 205 await self._client.container.delete( 206 timeout=timeout, 207 lease_access_conditions=access_conditions, 208 modified_access_conditions=mod_conditions, 209 **kwargs) 210 except StorageErrorException as error: 211 process_storage_error(error) 212 213 @distributed_trace_async 214 async def acquire_lease( 215 self, lease_duration=-1, # type: int 216 lease_id=None, # type: Optional[str] 217 **kwargs): 218 # type: (...) -> BlobLeaseClient 219 """ 220 Requests a new lease. If the container does not have an active lease, 221 the Blob service creates a lease on the container and returns a new 222 lease ID. 223 224 :param int lease_duration: 225 Specifies the duration of the lease, in seconds, or negative one 226 (-1) for a lease that never expires. A non-infinite lease can be 227 between 15 and 60 seconds. A lease duration cannot be changed 228 using renew or change. Default is -1 (infinite lease). 229 :param str lease_id: 230 Proposed lease ID, in a GUID string format. The Blob service returns 231 400 (Invalid request) if the proposed lease ID is not in the correct format. 232 :keyword ~datetime.datetime if_modified_since: 233 A DateTime value. Azure expects the date value passed in to be UTC. 234 If timezone is included, any non-UTC datetimes will be converted to UTC. 235 If a date is passed in without timezone info, it is assumed to be UTC. 236 Specify this header to perform the operation only 237 if the resource has been modified since the specified time. 238 :keyword ~datetime.datetime if_unmodified_since: 239 A DateTime value. Azure expects the date value passed in to be UTC. 240 If timezone is included, any non-UTC datetimes will be converted to UTC. 241 If a date is passed in without timezone info, it is assumed to be UTC. 242 Specify this header to perform the operation only if 243 the resource has not been modified since the specified date/time. 244 :keyword str etag: 245 An ETag value, or the wildcard character (*). Used to check if the resource has changed, 246 and act according to the condition specified by the `match_condition` parameter. 247 :keyword ~azure.core.MatchConditions match_condition: 248 The match condition to use upon the etag. 249 :keyword int timeout: 250 The timeout parameter is expressed in seconds. 251 :returns: A BlobLeaseClient object, that can be run in a context manager. 252 :rtype: ~azure.storage.blob.aio.BlobLeaseClient 253 254 .. admonition:: Example: 255 256 .. literalinclude:: ../samples/blob_samples_containers_async.py 257 :start-after: [START acquire_lease_on_container] 258 :end-before: [END acquire_lease_on_container] 259 :language: python 260 :dedent: 12 261 :caption: Acquiring a lease on the container. 262 """ 263 lease = BlobLeaseClient(self, lease_id=lease_id) # type: ignore 264 kwargs.setdefault('merge_span', True) 265 timeout = kwargs.pop('timeout', None) 266 await lease.acquire(lease_duration=lease_duration, timeout=timeout, **kwargs) 267 return lease 268 269 @distributed_trace_async 270 async def get_account_information(self, **kwargs): 271 # type: (**Any) -> Dict[str, str] 272 """Gets information related to the storage account. 273 274 The information can also be retrieved if the user has a SAS to a container or blob. 275 The keys in the returned dictionary include 'sku_name' and 'account_kind'. 276 277 :returns: A dict of account information (SKU and account type). 278 :rtype: dict(str, str) 279 """ 280 try: 281 return await self._client.container.get_account_info(cls=return_response_headers, **kwargs) # type: ignore 282 except StorageErrorException as error: 283 process_storage_error(error) 284 285 @distributed_trace_async 286 async def get_container_properties(self, **kwargs): 287 # type: (**Any) -> ContainerProperties 288 """Returns all user-defined metadata and system properties for the specified 289 container. The data returned does not include the container's list of blobs. 290 291 :keyword lease: 292 If specified, get_container_properties only succeeds if the 293 container's lease is active and matches this ID. 294 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 295 :keyword int timeout: 296 The timeout parameter is expressed in seconds. 297 :return: Properties for the specified container within a container object. 298 :rtype: ~azure.storage.blob.ContainerProperties 299 300 .. admonition:: Example: 301 302 .. literalinclude:: ../samples/blob_samples_containers_async.py 303 :start-after: [START get_container_properties] 304 :end-before: [END get_container_properties] 305 :language: python 306 :dedent: 16 307 :caption: Getting properties on the container. 308 """ 309 lease = kwargs.pop('lease', None) 310 access_conditions = get_access_conditions(lease) 311 timeout = kwargs.pop('timeout', None) 312 try: 313 response = await self._client.container.get_properties( 314 timeout=timeout, 315 lease_access_conditions=access_conditions, 316 cls=deserialize_container_properties, 317 **kwargs) 318 except StorageErrorException as error: 319 process_storage_error(error) 320 response.name = self.container_name 321 return response # type: ignore 322 323 @distributed_trace_async 324 async def set_container_metadata( # type: ignore 325 self, metadata=None, # type: Optional[Dict[str, str]] 326 **kwargs 327 ): 328 # type: (...) -> Dict[str, Union[str, datetime]] 329 """Sets one or more user-defined name-value pairs for the specified 330 container. Each call to this operation replaces all existing metadata 331 attached to the container. To remove all metadata from the container, 332 call this operation with no metadata dict. 333 334 :param metadata: 335 A dict containing name-value pairs to associate with the container as 336 metadata. Example: {'category':'test'} 337 :type metadata: dict[str, str] 338 :keyword lease: 339 If specified, set_container_metadata only succeeds if the 340 container's lease is active and matches this ID. 341 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 342 :keyword ~datetime.datetime if_modified_since: 343 A DateTime value. Azure expects the date value passed in to be UTC. 344 If timezone is included, any non-UTC datetimes will be converted to UTC. 345 If a date is passed in without timezone info, it is assumed to be UTC. 346 Specify this header to perform the operation only 347 if the resource has been modified since the specified time. 348 :keyword int timeout: 349 The timeout parameter is expressed in seconds. 350 :returns: Container-updated property dict (Etag and last modified). 351 352 .. admonition:: Example: 353 354 .. literalinclude:: ../samples/blob_samples_containers_async.py 355 :start-after: [START set_container_metadata] 356 :end-before: [END set_container_metadata] 357 :language: python 358 :dedent: 16 359 :caption: Setting metadata on the container. 360 """ 361 headers = kwargs.pop('headers', {}) 362 headers.update(add_metadata_headers(metadata)) 363 lease = kwargs.pop('lease', None) 364 access_conditions = get_access_conditions(lease) 365 mod_conditions = get_modify_conditions(kwargs) 366 timeout = kwargs.pop('timeout', None) 367 try: 368 return await self._client.container.set_metadata( # type: ignore 369 timeout=timeout, 370 lease_access_conditions=access_conditions, 371 modified_access_conditions=mod_conditions, 372 cls=return_response_headers, 373 headers=headers, 374 **kwargs) 375 except StorageErrorException as error: 376 process_storage_error(error) 377 378 @distributed_trace_async 379 async def get_container_access_policy(self, **kwargs): 380 # type: (Any) -> Dict[str, Any] 381 """Gets the permissions for the specified container. 382 The permissions indicate whether container data may be accessed publicly. 383 384 :keyword lease: 385 If specified, get_container_access_policy only succeeds if the 386 container's lease is active and matches this ID. 387 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 388 :keyword int timeout: 389 The timeout parameter is expressed in seconds. 390 :returns: Access policy information in a dict. 391 :rtype: dict[str, Any] 392 393 .. admonition:: Example: 394 395 .. literalinclude:: ../samples/blob_samples_containers_async.py 396 :start-after: [START get_container_access_policy] 397 :end-before: [END get_container_access_policy] 398 :language: python 399 :dedent: 16 400 :caption: Getting the access policy on the container. 401 """ 402 lease = kwargs.pop('lease', None) 403 access_conditions = get_access_conditions(lease) 404 timeout = kwargs.pop('timeout', None) 405 try: 406 response, identifiers = await self._client.container.get_access_policy( 407 timeout=timeout, 408 lease_access_conditions=access_conditions, 409 cls=return_headers_and_deserialized, 410 **kwargs) 411 except StorageErrorException as error: 412 process_storage_error(error) 413 return { 414 'public_access': response.get('blob_public_access'), 415 'signed_identifiers': identifiers or [] 416 } 417 418 @distributed_trace_async 419 async def set_container_access_policy( 420 self, signed_identifiers, # type: Dict[str, AccessPolicy] 421 public_access=None, # type: Optional[Union[str, PublicAccess]] 422 **kwargs # type: Any 423 ): # type: (...) -> Dict[str, Union[str, datetime]] 424 """Sets the permissions for the specified container or stored access 425 policies that may be used with Shared Access Signatures. The permissions 426 indicate whether blobs in a container may be accessed publicly. 427 428 :param signed_identifiers: 429 A dictionary of access policies to associate with the container. The 430 dictionary may contain up to 5 elements. An empty dictionary 431 will clear the access policies set on the service. 432 :type signed_identifiers: dict[str, ~azure.storage.blob.AccessPolicy] 433 :param ~azure.storage.blob.PublicAccess public_access: 434 Possible values include: 'container', 'blob'. 435 :keyword lease: 436 Required if the container has an active lease. Value can be a BlobLeaseClient object 437 or the lease ID as a string. 438 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 439 :keyword ~datetime.datetime if_modified_since: 440 A datetime value. Azure expects the date value passed in to be UTC. 441 If timezone is included, any non-UTC datetimes will be converted to UTC. 442 If a date is passed in without timezone info, it is assumed to be UTC. 443 Specify this header to perform the operation only 444 if the resource has been modified since the specified date/time. 445 :keyword ~datetime.datetime if_unmodified_since: 446 A datetime value. Azure expects the date value passed in to be UTC. 447 If timezone is included, any non-UTC datetimes will be converted to UTC. 448 If a date is passed in without timezone info, it is assumed to be UTC. 449 Specify this header to perform the operation only if 450 the resource has not been modified since the specified date/time. 451 :keyword int timeout: 452 The timeout parameter is expressed in seconds. 453 :returns: Container-updated property dict (Etag and last modified). 454 :rtype: dict[str, str or ~datetime.datetime] 455 456 .. admonition:: Example: 457 458 .. literalinclude:: ../samples/blob_samples_containers_async.py 459 :start-after: [START set_container_access_policy] 460 :end-before: [END set_container_access_policy] 461 :language: python 462 :dedent: 16 463 :caption: Setting access policy on the container. 464 """ 465 timeout = kwargs.pop('timeout', None) 466 lease = kwargs.pop('lease', None) 467 if len(signed_identifiers) > 5: 468 raise ValueError( 469 'Too many access policies provided. The server does not support setting ' 470 'more than 5 access policies on a single resource.') 471 identifiers = [] 472 for key, value in signed_identifiers.items(): 473 if value: 474 value.start = serialize_iso(value.start) 475 value.expiry = serialize_iso(value.expiry) 476 identifiers.append(SignedIdentifier(id=key, access_policy=value)) # type: ignore 477 signed_identifiers = identifiers # type: ignore 478 479 mod_conditions = get_modify_conditions(kwargs) 480 access_conditions = get_access_conditions(lease) 481 try: 482 return await self._client.container.set_access_policy( 483 container_acl=signed_identifiers or None, 484 timeout=timeout, 485 access=public_access, 486 lease_access_conditions=access_conditions, 487 modified_access_conditions=mod_conditions, 488 cls=return_response_headers, 489 **kwargs) 490 except StorageErrorException as error: 491 process_storage_error(error) 492 493 @distributed_trace 494 def list_blobs(self, name_starts_with=None, include=None, **kwargs): 495 # type: (Optional[str], Optional[Any], **Any) -> AsyncItemPaged[BlobProperties] 496 """Returns a generator to list the blobs under the specified container. 497 The generator will lazily follow the continuation tokens returned by 498 the service. 499 500 :param str name_starts_with: 501 Filters the results to return only blobs whose names 502 begin with the specified prefix. 503 :param list[str] include: 504 Specifies one or more additional datasets to include in the response. 505 Options include: 'snapshots', 'metadata', 'uncommittedblobs', 'copy', 'deleted'. 506 :keyword int timeout: 507 The timeout parameter is expressed in seconds. 508 :returns: An iterable (auto-paging) response of BlobProperties. 509 :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.storage.blob.BlobProperties] 510 511 .. admonition:: Example: 512 513 .. literalinclude:: ../samples/blob_samples_containers_async.py 514 :start-after: [START list_blobs_in_container] 515 :end-before: [END list_blobs_in_container] 516 :language: python 517 :dedent: 12 518 :caption: List the blobs in the container. 519 """ 520 if include and not isinstance(include, list): 521 include = [include] 522 523 results_per_page = kwargs.pop('results_per_page', None) 524 timeout = kwargs.pop('timeout', None) 525 command = functools.partial( 526 self._client.container.list_blob_flat_segment, 527 include=include, 528 timeout=timeout, 529 **kwargs) 530 return AsyncItemPaged( 531 command, 532 prefix=name_starts_with, 533 results_per_page=results_per_page, 534 page_iterator_class=BlobPropertiesPaged 535 ) 536 537 @distributed_trace 538 def walk_blobs( 539 self, name_starts_with=None, # type: Optional[str] 540 include=None, # type: Optional[Any] 541 delimiter="/", # type: str 542 **kwargs # type: Optional[Any] 543 ): 544 # type: (...) -> AsyncItemPaged[BlobProperties] 545 """Returns a generator to list the blobs under the specified container. 546 The generator will lazily follow the continuation tokens returned by 547 the service. This operation will list blobs in accordance with a hierarchy, 548 as delimited by the specified delimiter character. 549 550 :param str name_starts_with: 551 Filters the results to return only blobs whose names 552 begin with the specified prefix. 553 :param list[str] include: 554 Specifies one or more additional datasets to include in the response. 555 Options include: 'snapshots', 'metadata', 'uncommittedblobs', 'copy', 'deleted'. 556 :param str delimiter: 557 When the request includes this parameter, the operation returns a BlobPrefix 558 element in the response body that acts as a placeholder for all blobs whose 559 names begin with the same substring up to the appearance of the delimiter 560 character. The delimiter may be a single character or a string. 561 :keyword int timeout: 562 The timeout parameter is expressed in seconds. 563 :returns: An iterable (auto-paging) response of BlobProperties. 564 :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.storage.blob.BlobProperties] 565 """ 566 if include and not isinstance(include, list): 567 include = [include] 568 569 results_per_page = kwargs.pop('results_per_page', None) 570 timeout = kwargs.pop('timeout', None) 571 command = functools.partial( 572 self._client.container.list_blob_hierarchy_segment, 573 delimiter=delimiter, 574 include=include, 575 timeout=timeout, 576 **kwargs) 577 return BlobPrefix( 578 command, 579 prefix=name_starts_with, 580 results_per_page=results_per_page, 581 delimiter=delimiter) 582 583 @distributed_trace_async 584 async def upload_blob( 585 self, name, # type: Union[str, BlobProperties] 586 data, # type: Union[Iterable[AnyStr], IO[AnyStr]] 587 blob_type=BlobType.BlockBlob, # type: Union[str, BlobType] 588 length=None, # type: Optional[int] 589 metadata=None, # type: Optional[Dict[str, str]] 590 **kwargs 591 ): 592 # type: (...) -> BlobClient 593 """Creates a new blob from a data source with automatic chunking. 594 595 :param name: The blob with which to interact. If specified, this value will override 596 a blob value specified in the blob URL. 597 :type name: str or ~azure.storage.blob.BlobProperties 598 :param data: The blob data to upload. 599 :param ~azure.storage.blob.BlobType blob_type: The type of the blob. This can be 600 either BlockBlob, PageBlob or AppendBlob. The default value is BlockBlob. 601 :param int length: 602 Number of bytes to read from the stream. This is optional, but 603 should be supplied for optimal performance. 604 :param metadata: 605 Name-value pairs associated with the blob as metadata. 606 :type metadata: dict(str, str) 607 :keyword bool overwrite: Whether the blob to be uploaded should overwrite the current data. 608 If True, upload_blob will overwrite the existing data. If set to False, the 609 operation will fail with ResourceExistsError. The exception to the above is with Append 610 blob types: if set to False and the data already exists, an error will not be raised 611 and the data will be appended to the existing blob. If set overwrite=True, then the existing 612 append blob will be deleted, and a new one created. Defaults to False. 613 :keyword ~azure.storage.blob.ContentSettings content_settings: 614 ContentSettings object used to set blob properties. Used to set content type, encoding, 615 language, disposition, md5, and cache control. 616 :keyword bool validate_content: 617 If true, calculates an MD5 hash for each chunk of the blob. The storage 618 service checks the hash of the content that has arrived with the hash 619 that was sent. This is primarily valuable for detecting bitflips on 620 the wire if using http instead of https, as https (the default), will 621 already validate. Note that this MD5 hash is not stored with the 622 blob. Also note that if enabled, the memory-efficient upload algorithm 623 will not be used, because computing the MD5 hash requires buffering 624 entire blocks, and doing so defeats the purpose of the memory-efficient algorithm. 625 :keyword lease: 626 Required if the container has an active lease. Value can be a BlobLeaseClient object 627 or the lease ID as a string. 628 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 629 :keyword ~datetime.datetime if_modified_since: 630 A DateTime value. Azure expects the date value passed in to be UTC. 631 If timezone is included, any non-UTC datetimes will be converted to UTC. 632 If a date is passed in without timezone info, it is assumed to be UTC. 633 Specify this header to perform the operation only 634 if the resource has been modified since the specified time. 635 :keyword ~datetime.datetime if_unmodified_since: 636 A DateTime value. Azure expects the date value passed in to be UTC. 637 If timezone is included, any non-UTC datetimes will be converted to UTC. 638 If a date is passed in without timezone info, it is assumed to be UTC. 639 Specify this header to perform the operation only if 640 the resource has not been modified since the specified date/time. 641 :keyword str etag: 642 An ETag value, or the wildcard character (*). Used to check if the resource has changed, 643 and act according to the condition specified by the `match_condition` parameter. 644 :keyword ~azure.core.MatchConditions match_condition: 645 The match condition to use upon the etag. 646 :keyword int timeout: 647 The timeout parameter is expressed in seconds. This method may make 648 multiple calls to the Azure service and the timeout will apply to 649 each call individually. 650 :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier: 651 A page blob tier value to set the blob to. The tier correlates to the size of the 652 blob and number of allowed IOPS. This is only applicable to page blobs on 653 premium storage accounts. 654 :keyword ~azure.storage.blob.StandardBlobTier standard_blob_tier: 655 A standard blob tier value to set the blob to. For this version of the library, 656 this is only applicable to block blobs on standard storage accounts. 657 :keyword int maxsize_condition: 658 Optional conditional header. The max length in bytes permitted for 659 the append blob. If the Append Block operation would cause the blob 660 to exceed that limit or if the blob size is already greater than the 661 value specified in this header, the request will fail with 662 MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed). 663 :keyword int max_concurrency: 664 Maximum number of parallel connections to use when the blob size exceeds 665 64MB. 666 :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: 667 Encrypts the data on the service-side with the given key. 668 Use of customer-provided keys must be done over HTTPS. 669 As the encryption key itself is provided in the request, 670 a secure connection must be established to transfer the key. 671 :keyword str encoding: 672 Defaults to UTF-8. 673 :returns: A BlobClient to interact with the newly uploaded blob. 674 :rtype: ~azure.storage.blob.aio.BlobClient 675 676 .. admonition:: Example: 677 678 .. literalinclude:: ../samples/blob_samples_containers_async.py 679 :start-after: [START upload_blob_to_container] 680 :end-before: [END upload_blob_to_container] 681 :language: python 682 :dedent: 12 683 :caption: Upload blob to the container. 684 """ 685 blob = self.get_blob_client(name) 686 kwargs.setdefault('merge_span', True) 687 timeout = kwargs.pop('timeout', None) 688 encoding = kwargs.pop('encoding', 'UTF-8') 689 await blob.upload_blob( 690 data, 691 blob_type=blob_type, 692 length=length, 693 metadata=metadata, 694 timeout=timeout, 695 encoding=encoding, 696 **kwargs 697 ) 698 return blob 699 700 @distributed_trace_async 701 async def delete_blob( 702 self, blob, # type: Union[str, BlobProperties] 703 delete_snapshots=None, # type: Optional[str] 704 **kwargs 705 ): 706 # type: (...) -> None 707 """Marks the specified blob or snapshot for deletion. 708 709 The blob is later deleted during garbage collection. 710 Note that in order to delete a blob, you must delete all of its 711 snapshots. You can delete both at the same time with the delete_blob 712 operation. 713 714 If a delete retention policy is enabled for the service, then this operation soft deletes the blob or snapshot 715 and retains the blob or snapshot for specified number of days. 716 After specified number of days, blob's data is removed from the service during garbage collection. 717 Soft deleted blob or snapshot is accessible through :func:`list_blobs()` specifying `include=["deleted"]` 718 option. Soft-deleted blob or snapshot can be restored using :func:`~BlobClient.undelete()` 719 720 :param blob: The blob with which to interact. If specified, this value will override 721 a blob value specified in the blob URL. 722 :type blob: str or ~azure.storage.blob.BlobProperties 723 :param str delete_snapshots: 724 Required if the blob has associated snapshots. Values include: 725 - "only": Deletes only the blobs snapshots. 726 - "include": Deletes the blob along with all snapshots. 727 :keyword lease: 728 Required if the blob has an active lease. Value can be a Lease object 729 or the lease ID as a string. 730 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 731 :keyword ~datetime.datetime if_modified_since: 732 A DateTime value. Azure expects the date value passed in to be UTC. 733 If timezone is included, any non-UTC datetimes will be converted to UTC. 734 If a date is passed in without timezone info, it is assumed to be UTC. 735 Specify this header to perform the operation only 736 if the resource has been modified since the specified time. 737 :keyword ~datetime.datetime if_unmodified_since: 738 A DateTime value. Azure expects the date value passed in to be UTC. 739 If timezone is included, any non-UTC datetimes will be converted to UTC. 740 If a date is passed in without timezone info, it is assumed to be UTC. 741 Specify this header to perform the operation only if 742 the resource has not been modified since the specified date/time. 743 :keyword str etag: 744 An ETag value, or the wildcard character (*). Used to check if the resource has changed, 745 and act according to the condition specified by the `match_condition` parameter. 746 :keyword ~azure.core.MatchConditions match_condition: 747 The match condition to use upon the etag. 748 :keyword int timeout: 749 The timeout parameter is expressed in seconds. 750 :rtype: None 751 """ 752 blob = self.get_blob_client(blob) # type: ignore 753 kwargs.setdefault('merge_span', True) 754 timeout = kwargs.pop('timeout', None) 755 await blob.delete_blob( # type: ignore 756 delete_snapshots=delete_snapshots, 757 timeout=timeout, 758 **kwargs) 759 760 @distributed_trace_async 761 async def delete_blobs( # pylint: disable=arguments-differ 762 self, *blobs: Union[str, BlobProperties], 763 delete_snapshots: Optional[str] = None, 764 lease: Optional[Union[str, BlobLeaseClient]] = None, 765 **kwargs 766 ) -> AsyncIterator[AsyncHttpResponse]: 767 """Marks the specified blobs or snapshots for deletion. 768 769 The blobs are later deleted during garbage collection. 770 Note that in order to delete blobs, you must delete all of their 771 snapshots. You can delete both at the same time with the delete_blobs operation. 772 773 If a delete retention policy is enabled for the service, then this operation soft deletes the blobs or snapshots 774 and retains the blobs or snapshots for specified number of days. 775 After specified number of days, blobs' data is removed from the service during garbage collection. 776 Soft deleted blobs or snapshots are accessible through :func:`list_blobs()` specifying `include=["deleted"]` 777 Soft-deleted blobs or snapshots can be restored using :func:`~BlobClient.undelete()` 778 779 :param blobs: The blob names with which to interact. This can be a single blob, or multiple values can 780 be supplied, where each value is either the name of the blob (str) or BlobProperties. 781 :type blobs: str or ~azure.storage.blob.BlobProperties 782 :param str delete_snapshots: 783 Required if a blob has associated snapshots. Values include: 784 - "only": Deletes only the blobs snapshots. 785 - "include": Deletes the blob along with all snapshots. 786 :param lease: 787 Required if a blob has an active lease. Value can be a BlobLeaseClient object 788 or the lease ID as a string. 789 :type lease: ~azure.storage.blob.aio.BlobLeaseClient or str 790 :keyword ~datetime.datetime if_modified_since: 791 A DateTime value. Azure expects the date value passed in to be UTC. 792 If timezone is included, any non-UTC datetimes will be converted to UTC. 793 If a date is passed in without timezone info, it is assumed to be UTC. 794 Specify this header to perform the operation only 795 if the resource has been modified since the specified time. 796 :keyword ~datetime.datetime if_unmodified_since: 797 A DateTime value. Azure expects the date value passed in to be UTC. 798 If timezone is included, any non-UTC datetimes will be converted to UTC. 799 If a date is passed in without timezone info, it is assumed to be UTC. 800 Specify this header to perform the operation only if 801 the resource has not been modified since the specified date/time. 802 :keyword bool raise_on_any_failure: 803 This is a boolean param which defaults to True. When this is set, an exception 804 is raised even if there is a single operation failure. For optimal performance, 805 this should be set to False 806 :keyword str etag: 807 An ETag value, or the wildcard character (*). Used to check if the resource has changed, 808 and act according to the condition specified by the `match_condition` parameter. 809 :keyword ~azure.core.MatchConditions match_condition: 810 The match condition to use upon the etag. 811 :keyword int timeout: 812 The timeout parameter is expressed in seconds. 813 :return: An async iterator of responses, one for each blob in order 814 :rtype: asynciterator[~azure.core.pipeline.transport.AsyncHttpResponse] 815 816 .. admonition:: Example: 817 818 .. literalinclude:: ../samples/blob_samples_common_async.py 819 :start-after: [START delete_multiple_blobs] 820 :end-before: [END delete_multiple_blobs] 821 :language: python 822 :dedent: 12 823 :caption: Deleting multiple blobs. 824 """ 825 raise_on_any_failure = kwargs.pop('raise_on_any_failure', True) 826 timeout = kwargs.pop('timeout', None) 827 options = BlobClient._generic_delete_blob_options( # pylint: disable=protected-access 828 delete_snapshots=delete_snapshots, 829 lease=lease, 830 timeout=timeout, 831 **kwargs 832 ) 833 options.update({'raise_on_any_failure': raise_on_any_failure}) 834 query_parameters, header_parameters = self._generate_delete_blobs_options(**options) 835 # To pass kwargs to "_batch_send", we need to remove anything that was 836 # in the Autorest signature for Autorest, otherwise transport will be upset 837 for possible_param in ['timeout', 'delete_snapshots', 'lease_access_conditions', 'modified_access_conditions']: 838 options.pop(possible_param, None) 839 840 reqs = [] 841 for blob in blobs: 842 blob_name = _get_blob_name(blob) 843 req = HttpRequest( 844 "DELETE", 845 "/{}/{}".format(self.container_name, blob_name), 846 headers=header_parameters 847 ) 848 req.format_parameters(query_parameters) 849 reqs.append(req) 850 851 return await self._batch_send(*reqs, **options) 852 853 @distributed_trace 854 async def set_standard_blob_tier_blobs( 855 self, 856 standard_blob_tier: Union[str, 'StandardBlobTier'], 857 *blobs: Union[str, BlobProperties], 858 **kwargs 859 ) -> AsyncIterator[AsyncHttpResponse]: 860 """This operation sets the tier on block blobs. 861 862 A block blob's tier determines Hot/Cool/Archive storage type. 863 This operation does not update the blob's ETag. 864 865 :param standard_blob_tier: 866 Indicates the tier to be set on the blob. Options include 'Hot', 'Cool', 867 'Archive'. The hot tier is optimized for storing data that is accessed 868 frequently. The cool storage tier is optimized for storing data that 869 is infrequently accessed and stored for at least a month. The archive 870 tier is optimized for storing data that is rarely accessed and stored 871 for at least six months with flexible latency requirements. 872 :type standard_blob_tier: str or ~azure.storage.blob.StandardBlobTier 873 :param blobs: The blobs with which to interact. This can be a single blob, or multiple values can 874 be supplied, where each value is either the name of the blob (str) or BlobProperties. 875 :type blobs: str or ~azure.storage.blob.BlobProperties 876 :keyword int timeout: 877 The timeout parameter is expressed in seconds. 878 :keyword lease: 879 Required if the blob has an active lease. Value can be a BlobLeaseClient object 880 or the lease ID as a string. 881 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 882 :keyword bool raise_on_any_failure: 883 This is a boolean param which defaults to True. When this is set, an exception 884 is raised even if there is a single operation failure. For optimal performance, 885 this should be set to False. 886 :return: An async iterator of responses, one for each blob in order 887 :rtype: asynciterator[~azure.core.pipeline.transport.AsyncHttpResponse] 888 """ 889 access_conditions = get_access_conditions(kwargs.pop('lease', None)) 890 if standard_blob_tier is None: 891 raise ValueError("A StandardBlobTier must be specified") 892 893 query_parameters, header_parameters = self._generate_set_tier_options( 894 tier=standard_blob_tier, 895 lease_access_conditions=access_conditions, 896 **kwargs 897 ) 898 # To pass kwargs to "_batch_send", we need to remove anything that was 899 # in the Autorest signature for Autorest, otherwise transport will be upset 900 for possible_param in ['timeout', 'lease']: 901 kwargs.pop(possible_param, None) 902 903 reqs = [] 904 for blob in blobs: 905 blob_name = _get_blob_name(blob) 906 req = HttpRequest( 907 "PUT", 908 "/{}/{}".format(self.container_name, blob_name), 909 headers=header_parameters 910 ) 911 req.format_parameters(query_parameters) 912 reqs.append(req) 913 914 return await self._batch_send(*reqs, **kwargs) 915 916 @distributed_trace 917 async def set_premium_page_blob_tier_blobs( 918 self, 919 premium_page_blob_tier: Union[str, 'PremiumPageBlobTier'], 920 *blobs: Union[str, BlobProperties], 921 **kwargs 922 ) -> AsyncIterator[AsyncHttpResponse]: 923 """Sets the page blob tiers on the blobs. This API is only supported for page blobs on premium accounts. 924 925 :param premium_page_blob_tier: 926 A page blob tier value to set the blob to. The tier correlates to the size of the 927 blob and number of allowed IOPS. This is only applicable to page blobs on 928 premium storage accounts. 929 :type premium_page_blob_tier: ~azure.storage.blob.PremiumPageBlobTier 930 :param blobs: The blobs with which to interact. This can be a single blob, or multiple values can 931 be supplied, where each value is either the name of the blob (str) or BlobProperties. 932 :type blobs: str or ~azure.storage.blob.BlobProperties 933 :keyword int timeout: 934 The timeout parameter is expressed in seconds. This method may make 935 multiple calls to the Azure service and the timeout will apply to 936 each call individually. 937 :keyword lease: 938 Required if the blob has an active lease. Value can be a BlobLeaseClient object 939 or the lease ID as a string. 940 :paramtype lease: ~azure.storage.blob.aio.BlobLeaseClient or str 941 :keyword bool raise_on_any_failure: 942 This is a boolean param which defaults to True. When this is set, an exception 943 is raised even if there is a single operation failure. For optimal performance, 944 this should be set to False. 945 :return: An async iterator of responses, one for each blob in order 946 :rtype: asynciterator[~azure.core.pipeline.transport.AsyncHttpResponse] 947 """ 948 access_conditions = get_access_conditions(kwargs.pop('lease', None)) 949 if premium_page_blob_tier is None: 950 raise ValueError("A PremiumPageBlobTier must be specified") 951 952 query_parameters, header_parameters = self._generate_set_tier_options( 953 tier=premium_page_blob_tier, 954 lease_access_conditions=access_conditions, 955 **kwargs 956 ) 957 # To pass kwargs to "_batch_send", we need to remove anything that was 958 # in the Autorest signature for Autorest, otherwise transport will be upset 959 for possible_param in ['timeout', 'lease']: 960 kwargs.pop(possible_param, None) 961 962 reqs = [] 963 for blob in blobs: 964 blob_name = _get_blob_name(blob) 965 req = HttpRequest( 966 "PUT", 967 "/{}/{}".format(self.container_name, blob_name), 968 headers=header_parameters 969 ) 970 req.format_parameters(query_parameters) 971 reqs.append(req) 972 973 return await self._batch_send(*reqs, **kwargs) 974 975 def get_blob_client( 976 self, blob, # type: Union[BlobProperties, str] 977 snapshot=None # type: str 978 ): 979 # type: (...) -> BlobClient 980 """Get a client to interact with the specified blob. 981 982 The blob need not already exist. 983 984 :param blob: 985 The blob with which to interact. 986 :type blob: str or ~azure.storage.blob.BlobProperties 987 :param str snapshot: 988 The optional blob snapshot on which to operate. This can be the snapshot ID string 989 or the response returned from :func:`~BlobClient.create_snapshot()`. 990 :returns: A BlobClient. 991 :rtype: ~azure.storage.blob.aio.BlobClient 992 993 .. admonition:: Example: 994 995 .. literalinclude:: ../samples/blob_samples_containers_async.py 996 :start-after: [START get_blob_client] 997 :end-before: [END get_blob_client] 998 :language: python 999 :dedent: 12 1000 :caption: Get the blob client. 1001 """ 1002 blob_name = _get_blob_name(blob) 1003 _pipeline = AsyncPipeline( 1004 transport=AsyncTransportWrapper(self._pipeline._transport), # pylint: disable = protected-access 1005 policies=self._pipeline._impl_policies # pylint: disable = protected-access 1006 ) 1007 return BlobClient( 1008 self.url, container_name=self.container_name, blob_name=blob_name, snapshot=snapshot, 1009 credential=self.credential, _configuration=self._config, 1010 _pipeline=_pipeline, _location_mode=self._location_mode, _hosts=self._hosts, 1011 require_encryption=self.require_encryption, key_encryption_key=self.key_encryption_key, 1012 key_resolver_function=self.key_resolver_function, loop=self._loop) 1013