1# ------------------------------------------------------------------------- 2# Copyright (c) Microsoft Corporation. All rights reserved. 3# Licensed under the MIT License. See License.txt in the project root for 4# license information. 5# -------------------------------------------------------------------------- 6import sys 7from abc import ABCMeta 8 9from azure.common import AzureHttpError 10 11from ..common._auth import ( 12 _StorageSASAuthentication, 13 _StorageSharedKeyAuthentication, 14 _StorageNoAuthentication, 15) 16from ..common._common_conversion import ( 17 _int_to_str, 18 _to_str, 19 _datetime_to_utc_string, 20) 21from ..common._connection import _ServiceParameters 22from ..common._constants import ( 23 SERVICE_HOST_BASE, 24 DEFAULT_PROTOCOL, 25) 26from ..common._deserialization import ( 27 _convert_xml_to_service_properties, 28 _parse_metadata, 29 _parse_properties, 30 _convert_xml_to_service_stats, 31 _parse_length_from_content_range, 32) 33from ..common._error import ( 34 _dont_fail_not_exist, 35 _dont_fail_on_exist, 36 _validate_not_none, 37 _validate_decryption_required, 38 _validate_access_policies, 39 _ERROR_PARALLEL_NOT_SEEKABLE, 40) 41from ..common._http import HTTPRequest 42from ..common._serialization import ( 43 _get_request_body, 44 _convert_signed_identifiers_to_xml, 45 _convert_service_properties_to_xml, 46 _add_metadata_headers, 47) 48from ..common.models import ( 49 Services, 50 ListGenerator, 51 _OperationContext, 52) 53from .sharedaccesssignature import ( 54 BlobSharedAccessSignature, 55) 56from ..common.storageclient import StorageClient 57from ._deserialization import ( 58 _convert_xml_to_containers, 59 _parse_blob, 60 _convert_xml_to_blob_list, 61 _parse_container, 62 _parse_snapshot_blob, 63 _parse_lease, 64 _convert_xml_to_signed_identifiers_and_access, 65 _parse_base_properties, 66) 67from ._download_chunking import _download_blob_chunks 68from ._error import ( 69 _ERROR_INVALID_LEASE_DURATION, 70 _ERROR_INVALID_LEASE_BREAK_PERIOD, 71) 72from ._serialization import ( 73 _get_path, 74 _validate_and_format_range_headers, 75) 76from .models import ( 77 BlobProperties, 78 _LeaseActions, 79 ContainerPermissions, 80 BlobPermissions, 81) 82 83from ._constants import ( 84 X_MS_VERSION, 85 __version__ as package_version, 86) 87 88if sys.version_info >= (3,): 89 from io import BytesIO 90else: 91 from cStringIO import StringIO as BytesIO 92 93 94class BaseBlobService(StorageClient): 95 ''' 96 This is the main class managing Blob resources. 97 98 The Blob service stores text and binary data as blobs in the cloud. 99 The Blob service offers the following three resources: the storage account, 100 containers, and blobs. Within your storage account, containers provide a 101 way to organize sets of blobs. For more information please see: 102 https://msdn.microsoft.com/en-us/library/azure/ee691964.aspx 103 104 :ivar int MAX_SINGLE_GET_SIZE: 105 The size of the first range get performed by get_blob_to_* methods if 106 max_connections is greater than 1. Less data will be returned if the 107 blob is smaller than this. 108 :ivar int MAX_CHUNK_GET_SIZE: 109 The size of subsequent range gets performed by get_blob_to_* methods if 110 max_connections is greater than 1 and the blob is larger than MAX_SINGLE_GET_SIZE. 111 Less data will be returned if the remainder of the blob is smaller than 112 this. If this is set to larger than 4MB, content_validation will throw an 113 error if enabled. However, if content_validation is not desired a size 114 greater than 4MB may be optimal. Setting this below 4MB is not recommended. 115 :ivar object key_encryption_key: 116 The key-encryption-key optionally provided by the user. If provided, will be used to 117 encrypt/decrypt in supported methods. 118 For methods requiring decryption, either the key_encryption_key OR the resolver must be provided. 119 If both are provided, the resolver will take precedence. 120 Must implement the following methods for APIs requiring encryption: 121 wrap_key(key)--wraps the specified key (bytes) using an algorithm of the user's choice. Returns the encrypted key as bytes. 122 get_key_wrap_algorithm()--returns the algorithm used to wrap the specified symmetric key. 123 get_kid()--returns a string key id for this key-encryption-key. 124 Must implement the following methods for APIs requiring decryption: 125 unwrap_key(key, algorithm)--returns the unwrapped form of the specified symmetric key using the string-specified algorithm. 126 get_kid()--returns a string key id for this key-encryption-key. 127 :ivar function key_resolver_function(kid): 128 A function to resolve keys optionally provided by the user. If provided, will be used to decrypt in supported methods. 129 For methods requiring decryption, either the key_encryption_key OR 130 the resolver must be provided. If both are provided, the resolver will take precedence. 131 It uses the kid string to return a key-encryption-key implementing the interface defined above. 132 :ivar bool require_encryption: 133 A flag that may be set to ensure that all messages successfully uploaded to the queue and all those downloaded and 134 successfully read from the queue are/were encrypted while on the server. If this flag is set, all required 135 parameters for encryption/decryption must be provided. See the above comments on the key_encryption_key and resolver. 136 ''' 137 138 __metaclass__ = ABCMeta 139 MAX_SINGLE_GET_SIZE = 32 * 1024 * 1024 140 MAX_CHUNK_GET_SIZE = 4 * 1024 * 1024 141 142 def __init__(self, account_name=None, account_key=None, sas_token=None, is_emulated=False, 143 protocol=DEFAULT_PROTOCOL, endpoint_suffix=SERVICE_HOST_BASE, custom_domain=None, request_session=None, 144 connection_string=None, socket_timeout=None, token_credential=None): 145 ''' 146 :param str account_name: 147 The storage account name. This is used to authenticate requests 148 signed with an account key and to construct the storage endpoint. It 149 is required unless a connection string is given, or if a custom 150 domain is used with anonymous authentication. 151 :param str account_key: 152 The storage account key. This is used for shared key authentication. 153 If neither account key or sas token is specified, anonymous access 154 will be used. 155 :param str sas_token: 156 A shared access signature token to use to authenticate requests 157 instead of the account key. If account key and sas token are both 158 specified, account key will be used to sign. If neither are 159 specified, anonymous access will be used. 160 :param bool is_emulated: 161 Whether to use the emulator. Defaults to False. If specified, will 162 override all other parameters besides connection string and request 163 session. 164 :param str protocol: 165 The protocol to use for requests. Defaults to https. 166 :param str endpoint_suffix: 167 The host base component of the url, minus the account name. Defaults 168 to Azure (core.windows.net). Override this to use the China cloud 169 (core.chinacloudapi.cn). 170 :param str custom_domain: 171 The custom domain to use. This can be set in the Azure Portal. For 172 example, 'www.mydomain.com'. 173 :param requests.Session request_session: 174 The session object to use for http requests. 175 :param str connection_string: 176 If specified, this will override all other parameters besides 177 request session. See 178 http://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/ 179 for the connection string format 180 :param int socket_timeout: 181 If specified, this will override the default socket timeout. The timeout specified is in seconds. 182 See DEFAULT_SOCKET_TIMEOUT in _constants.py for the default value. 183 :param token_credential: 184 A token credential used to authenticate HTTPS requests. The token value 185 should be updated before its expiration. 186 :type `~azure.storage.common.TokenCredential` 187 ''' 188 service_params = _ServiceParameters.get_service_parameters( 189 'blob', 190 account_name=account_name, 191 account_key=account_key, 192 sas_token=sas_token, 193 token_credential=token_credential, 194 is_emulated=is_emulated, 195 protocol=protocol, 196 endpoint_suffix=endpoint_suffix, 197 custom_domain=custom_domain, 198 request_session=request_session, 199 connection_string=connection_string, 200 socket_timeout=socket_timeout) 201 202 super(BaseBlobService, self).__init__(service_params) 203 204 if self.account_key: 205 self.authentication = _StorageSharedKeyAuthentication( 206 self.account_name, 207 self.account_key, 208 self.is_emulated 209 ) 210 elif self.sas_token: 211 self.authentication = _StorageSASAuthentication(self.sas_token) 212 elif self.token_credential: 213 self.authentication = self.token_credential 214 else: 215 self.authentication = _StorageNoAuthentication() 216 217 self.require_encryption = False 218 self.key_encryption_key = None 219 self.key_resolver_function = None 220 self._X_MS_VERSION = X_MS_VERSION 221 self._update_user_agent_string(package_version) 222 223 def make_blob_url(self, container_name, blob_name, protocol=None, sas_token=None, snapshot=None): 224 ''' 225 Creates the url to access a blob. 226 227 :param str container_name: 228 Name of container. 229 :param str blob_name: 230 Name of blob. 231 :param str protocol: 232 Protocol to use: 'http' or 'https'. If not specified, uses the 233 protocol specified when BaseBlobService was initialized. 234 :param str sas_token: 235 Shared access signature token created with 236 generate_shared_access_signature. 237 :param str snapshot: 238 An string value that uniquely identifies the snapshot. The value of 239 this query parameter indicates the snapshot version. 240 :return: blob access URL. 241 :rtype: str 242 ''' 243 244 url = '{}://{}/{}/{}'.format( 245 protocol or self.protocol, 246 self.primary_endpoint, 247 container_name, 248 blob_name, 249 ) 250 251 if snapshot and sas_token: 252 url = '{}?snapshot={}&{}'.format(url, snapshot, sas_token) 253 elif snapshot: 254 url = '{}?snapshot={}'.format(url, snapshot) 255 elif sas_token: 256 url = '{}?{}'.format(url, sas_token) 257 258 return url 259 260 def make_container_url(self, container_name, protocol=None, sas_token=None): 261 ''' 262 Creates the url to access a container. 263 264 :param str container_name: 265 Name of container. 266 :param str protocol: 267 Protocol to use: 'http' or 'https'. If not specified, uses the 268 protocol specified when BaseBlobService was initialized. 269 :param str sas_token: 270 Shared access signature token created with 271 generate_shared_access_signature. 272 :return: container access URL. 273 :rtype: str 274 ''' 275 276 url = '{}://{}/{}?restype=container'.format( 277 protocol or self.protocol, 278 self.primary_endpoint, 279 container_name, 280 ) 281 282 if sas_token: 283 url = '{}&{}'.format(url, sas_token) 284 285 return url 286 287 def generate_account_shared_access_signature(self, resource_types, permission, 288 expiry, start=None, ip=None, protocol=None): 289 ''' 290 Generates a shared access signature for the blob service. 291 Use the returned signature with the sas_token parameter of any BlobService. 292 293 :param ResourceTypes resource_types: 294 Specifies the resource types that are accessible with the account SAS. 295 :param AccountPermissions permission: 296 The permissions associated with the shared access signature. The 297 user is restricted to operations allowed by the permissions. 298 Required unless an id is given referencing a stored access policy 299 which contains this field. This field must be omitted if it has been 300 specified in an associated stored access policy. 301 :param expiry: 302 The time at which the shared access signature becomes invalid. 303 Required unless an id is given referencing a stored access policy 304 which contains this field. This field must be omitted if it has 305 been specified in an associated stored access policy. Azure will always 306 convert values to UTC. If a date is passed in without timezone info, it 307 is assumed to be UTC. 308 :type expiry: datetime or str 309 :param start: 310 The time at which the shared access signature becomes valid. If 311 omitted, start time for this call is assumed to be the time when the 312 storage service receives the request. Azure will always convert values 313 to UTC. If a date is passed in without timezone info, it is assumed to 314 be UTC. 315 :type start: datetime or str 316 :param str ip: 317 Specifies an IP address or a range of IP addresses from which to accept requests. 318 If the IP address from which the request originates does not match the IP address 319 or address range specified on the SAS token, the request is not authenticated. 320 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 321 restricts the request to those IP addresses. 322 :param str protocol: 323 Specifies the protocol permitted for a request made. The default value 324 is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values. 325 :return: A Shared Access Signature (sas) token. 326 :rtype: str 327 ''' 328 _validate_not_none('self.account_name', self.account_name) 329 _validate_not_none('self.account_key', self.account_key) 330 331 sas = BlobSharedAccessSignature(self.account_name, self.account_key) 332 return sas.generate_account(Services.BLOB, resource_types, permission, 333 expiry, start=start, ip=ip, protocol=protocol) 334 335 def generate_container_shared_access_signature(self, container_name, 336 permission=None, expiry=None, 337 start=None, id=None, ip=None, protocol=None, 338 cache_control=None, content_disposition=None, 339 content_encoding=None, content_language=None, 340 content_type=None): 341 ''' 342 Generates a shared access signature for the container. 343 Use the returned signature with the sas_token parameter of any BlobService. 344 345 :param str container_name: 346 Name of container. 347 :param ContainerPermissions permission: 348 The permissions associated with the shared access signature. The 349 user is restricted to operations allowed by the permissions. 350 Permissions must be ordered read, write, delete, list. 351 Required unless an id is given referencing a stored access policy 352 which contains this field. This field must be omitted if it has been 353 specified in an associated stored access policy. 354 :param expiry: 355 The time at which the shared access signature becomes invalid. 356 Required unless an id is given referencing a stored access policy 357 which contains this field. This field must be omitted if it has 358 been specified in an associated stored access policy. Azure will always 359 convert values to UTC. If a date is passed in without timezone info, it 360 is assumed to be UTC. 361 :type expiry: datetime or str 362 :param start: 363 The time at which the shared access signature becomes valid. If 364 omitted, start time for this call is assumed to be the time when the 365 storage service receives the request. Azure will always convert values 366 to UTC. If a date is passed in without timezone info, it is assumed to 367 be UTC. 368 :type start: datetime or str 369 :param str id: 370 A unique value up to 64 characters in length that correlates to a 371 stored access policy. To create a stored access policy, use 372 set_blob_service_properties. 373 :param str ip: 374 Specifies an IP address or a range of IP addresses from which to accept requests. 375 If the IP address from which the request originates does not match the IP address 376 or address range specified on the SAS token, the request is not authenticated. 377 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 378 restricts the request to those IP addresses. 379 :param str protocol: 380 Specifies the protocol permitted for a request made. The default value 381 is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values. 382 :param str cache_control: 383 Response header value for Cache-Control when resource is accessed 384 using this shared access signature. 385 :param str content_disposition: 386 Response header value for Content-Disposition when resource is accessed 387 using this shared access signature. 388 :param str content_encoding: 389 Response header value for Content-Encoding when resource is accessed 390 using this shared access signature. 391 :param str content_language: 392 Response header value for Content-Language when resource is accessed 393 using this shared access signature. 394 :param str content_type: 395 Response header value for Content-Type when resource is accessed 396 using this shared access signature. 397 :return: A Shared Access Signature (sas) token. 398 :rtype: str 399 ''' 400 _validate_not_none('container_name', container_name) 401 _validate_not_none('self.account_name', self.account_name) 402 _validate_not_none('self.account_key', self.account_key) 403 404 sas = BlobSharedAccessSignature(self.account_name, self.account_key) 405 return sas.generate_container( 406 container_name, 407 permission, 408 expiry, 409 start=start, 410 id=id, 411 ip=ip, 412 protocol=protocol, 413 cache_control=cache_control, 414 content_disposition=content_disposition, 415 content_encoding=content_encoding, 416 content_language=content_language, 417 content_type=content_type, 418 ) 419 420 def generate_blob_shared_access_signature( 421 self, container_name, blob_name, permission=None, 422 expiry=None, start=None, id=None, ip=None, protocol=None, 423 cache_control=None, content_disposition=None, 424 content_encoding=None, content_language=None, 425 content_type=None): 426 ''' 427 Generates a shared access signature for the blob. 428 Use the returned signature with the sas_token parameter of any BlobService. 429 430 :param str container_name: 431 Name of container. 432 :param str blob_name: 433 Name of blob. 434 :param BlobPermissions permission: 435 The permissions associated with the shared access signature. The 436 user is restricted to operations allowed by the permissions. 437 Permissions must be ordered read, write, delete, list. 438 Required unless an id is given referencing a stored access policy 439 which contains this field. This field must be omitted if it has been 440 specified in an associated stored access policy. 441 :param expiry: 442 The time at which the shared access signature becomes invalid. 443 Required unless an id is given referencing a stored access policy 444 which contains this field. This field must be omitted if it has 445 been specified in an associated stored access policy. Azure will always 446 convert values to UTC. If a date is passed in without timezone info, it 447 is assumed to be UTC. 448 :type expiry: datetime or str 449 :param start: 450 The time at which the shared access signature becomes valid. If 451 omitted, start time for this call is assumed to be the time when the 452 storage service receives the request. Azure will always convert values 453 to UTC. If a date is passed in without timezone info, it is assumed to 454 be UTC. 455 :type start: datetime or str 456 :param str id: 457 A unique value up to 64 characters in length that correlates to a 458 stored access policy. To create a stored access policy, use :func:`~set_container_acl`. 459 :param str ip: 460 Specifies an IP address or a range of IP addresses from which to accept requests. 461 If the IP address from which the request originates does not match the IP address 462 or address range specified on the SAS token, the request is not authenticated. 463 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 464 restricts the request to those IP addresses. 465 :param str protocol: 466 Specifies the protocol permitted for a request made. The default value 467 is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values. 468 :param str cache_control: 469 Response header value for Cache-Control when resource is accessed 470 using this shared access signature. 471 :param str content_disposition: 472 Response header value for Content-Disposition when resource is accessed 473 using this shared access signature. 474 :param str content_encoding: 475 Response header value for Content-Encoding when resource is accessed 476 using this shared access signature. 477 :param str content_language: 478 Response header value for Content-Language when resource is accessed 479 using this shared access signature. 480 :param str content_type: 481 Response header value for Content-Type when resource is accessed 482 using this shared access signature. 483 :return: A Shared Access Signature (sas) token. 484 :rtype: str 485 ''' 486 _validate_not_none('container_name', container_name) 487 _validate_not_none('blob_name', blob_name) 488 _validate_not_none('self.account_name', self.account_name) 489 _validate_not_none('self.account_key', self.account_key) 490 491 sas = BlobSharedAccessSignature(self.account_name, self.account_key) 492 return sas.generate_blob( 493 container_name, 494 blob_name, 495 permission, 496 expiry, 497 start=start, 498 id=id, 499 ip=ip, 500 protocol=protocol, 501 cache_control=cache_control, 502 content_disposition=content_disposition, 503 content_encoding=content_encoding, 504 content_language=content_language, 505 content_type=content_type, 506 ) 507 508 def list_containers(self, prefix=None, num_results=None, include_metadata=False, 509 marker=None, timeout=None): 510 ''' 511 Returns a generator to list the containers under the specified account. 512 The generator will lazily follow the continuation tokens returned by 513 the service and stop when all containers have been returned or num_results is reached. 514 515 If num_results is specified and the account has more than that number of 516 containers, the generator will have a populated next_marker field once it 517 finishes. This marker can be used to create a new generator if more 518 results are desired. 519 520 :param str prefix: 521 Filters the results to return only containers whose names 522 begin with the specified prefix. 523 :param int num_results: 524 Specifies the maximum number of containers to return. A single list 525 request may return up to 1000 contianers and potentially a continuation 526 token which should be followed to get additional resutls. 527 :param bool include_metadata: 528 Specifies that container metadata be returned in the response. 529 :param str marker: 530 An opaque continuation token. This value can be retrieved from the 531 next_marker field of a previous generator object if num_results was 532 specified and that generator has finished enumerating results. If 533 specified, this generator will begin returning results from the point 534 where the previous generator stopped. 535 :param int timeout: 536 The timeout parameter is expressed in seconds. 537 ''' 538 include = 'metadata' if include_metadata else None 539 operation_context = _OperationContext(location_lock=True) 540 kwargs = {'prefix': prefix, 'marker': marker, 'max_results': num_results, 541 'include': include, 'timeout': timeout, '_context': operation_context} 542 resp = self._list_containers(**kwargs) 543 544 return ListGenerator(resp, self._list_containers, (), kwargs) 545 546 def _list_containers(self, prefix=None, marker=None, max_results=None, 547 include=None, timeout=None, _context=None): 548 ''' 549 Returns a list of the containers under the specified account. 550 551 :param str prefix: 552 Filters the results to return only containers whose names 553 begin with the specified prefix. 554 :param str marker: 555 A string value that identifies the portion of the list 556 to be returned with the next list operation. The operation returns 557 a next_marker value within the response body if the list returned was 558 not complete. The marker value may then be used in a subsequent 559 call to request the next set of list items. The marker value is 560 opaque to the client. 561 :param int max_results: 562 Specifies the maximum number of containers to return. A single list 563 request may return up to 1000 contianers and potentially a continuation 564 token which should be followed to get additional resutls. 565 :param str include: 566 Include this parameter to specify that the container's 567 metadata be returned as part of the response body. set this 568 parameter to string 'metadata' to get container's metadata. 569 :param int timeout: 570 The timeout parameter is expressed in seconds. 571 ''' 572 request = HTTPRequest() 573 request.method = 'GET' 574 request.host_locations = self._get_host_locations(secondary=True) 575 request.path = _get_path() 576 request.query = { 577 'comp': 'list', 578 'prefix': _to_str(prefix), 579 'marker': _to_str(marker), 580 'maxresults': _int_to_str(max_results), 581 'include': _to_str(include), 582 'timeout': _int_to_str(timeout) 583 } 584 585 return self._perform_request(request, _convert_xml_to_containers, operation_context=_context) 586 587 def create_container(self, container_name, metadata=None, 588 public_access=None, fail_on_exist=False, timeout=None): 589 ''' 590 Creates a new container under the specified account. If the container 591 with the same name already exists, the operation fails if 592 fail_on_exist is True. 593 594 :param str container_name: 595 Name of container to create. 596 :param metadata: 597 A dict with name_value pairs to associate with the 598 container as metadata. Example:{'Category':'test'} 599 :type metadata: dict(str, str) 600 :param ~azure.storage.blob.models.PublicAccess public_access: 601 Possible values include: container, blob. 602 :param bool fail_on_exist: 603 Specify whether to throw an exception when the container exists. 604 :param int timeout: 605 The timeout parameter is expressed in seconds. 606 :return: True if container is created, False if container already exists. 607 :rtype: bool 608 ''' 609 _validate_not_none('container_name', container_name) 610 request = HTTPRequest() 611 request.method = 'PUT' 612 request.host_locations = self._get_host_locations() 613 request.path = _get_path(container_name) 614 request.query = { 615 'restype': 'container', 616 'timeout': _int_to_str(timeout), 617 } 618 request.headers = { 619 'x-ms-blob-public-access': _to_str(public_access) 620 } 621 _add_metadata_headers(metadata, request) 622 623 if not fail_on_exist: 624 try: 625 self._perform_request(request) 626 return True 627 except AzureHttpError as ex: 628 _dont_fail_on_exist(ex) 629 return False 630 else: 631 self._perform_request(request) 632 return True 633 634 def get_container_properties(self, container_name, lease_id=None, timeout=None): 635 ''' 636 Returns all user-defined metadata and system properties for the specified 637 container. The data returned does not include the container's list of blobs. 638 639 :param str container_name: 640 Name of existing container. 641 :param str lease_id: 642 If specified, get_container_properties only succeeds if the 643 container's lease is active and matches this ID. 644 :param int timeout: 645 The timeout parameter is expressed in seconds. 646 :return: properties for the specified container within a container object. 647 :rtype: :class:`~azure.storage.blob.models.Container` 648 ''' 649 _validate_not_none('container_name', container_name) 650 request = HTTPRequest() 651 request.method = 'GET' 652 request.host_locations = self._get_host_locations(secondary=True) 653 request.path = _get_path(container_name) 654 request.query = { 655 'restype': 'container', 656 'timeout': _int_to_str(timeout), 657 } 658 request.headers = {'x-ms-lease-id': _to_str(lease_id)} 659 660 return self._perform_request(request, _parse_container, [container_name]) 661 662 def get_container_metadata(self, container_name, lease_id=None, timeout=None): 663 ''' 664 Returns all user-defined metadata for the specified container. 665 666 :param str container_name: 667 Name of existing container. 668 :param str lease_id: 669 If specified, get_container_metadata only succeeds if the 670 container's lease is active and matches this ID. 671 :param int timeout: 672 The timeout parameter is expressed in seconds. 673 :return: 674 A dictionary representing the container metadata name, value pairs. 675 :rtype: dict(str, str) 676 ''' 677 _validate_not_none('container_name', container_name) 678 request = HTTPRequest() 679 request.method = 'GET' 680 request.host_locations = self._get_host_locations(secondary=True) 681 request.path = _get_path(container_name) 682 request.query = { 683 'restype': 'container', 684 'comp': 'metadata', 685 'timeout': _int_to_str(timeout), 686 } 687 request.headers = {'x-ms-lease-id': _to_str(lease_id)} 688 689 return self._perform_request(request, _parse_metadata) 690 691 def set_container_metadata(self, container_name, metadata=None, 692 lease_id=None, if_modified_since=None, timeout=None): 693 ''' 694 Sets one or more user-defined name-value pairs for the specified 695 container. Each call to this operation replaces all existing metadata 696 attached to the container. To remove all metadata from the container, 697 call this operation with no metadata dict. 698 699 :param str container_name: 700 Name of existing container. 701 :param metadata: 702 A dict containing name-value pairs to associate with the container as 703 metadata. Example: {'category':'test'} 704 :type metadata: dict(str, str) 705 :param str lease_id: 706 If specified, set_container_metadata only succeeds if the 707 container's lease is active and matches this ID. 708 :param datetime if_modified_since: 709 A DateTime value. Azure expects the date value passed in to be UTC. 710 If timezone is included, any non-UTC datetimes will be converted to UTC. 711 If a date is passed in without timezone info, it is assumed to be UTC. 712 Specify this header to perform the operation only 713 if the resource has been modified since the specified time. 714 :param int timeout: 715 The timeout parameter is expressed in seconds. 716 :return: ETag and last modified properties for the updated Container 717 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 718 ''' 719 _validate_not_none('container_name', container_name) 720 request = HTTPRequest() 721 request.method = 'PUT' 722 request.host_locations = self._get_host_locations() 723 request.path = _get_path(container_name) 724 request.query = { 725 'restype': 'container', 726 'comp': 'metadata', 727 'timeout': _int_to_str(timeout), 728 } 729 request.headers = { 730 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 731 'x-ms-lease-id': _to_str(lease_id), 732 } 733 _add_metadata_headers(metadata, request) 734 735 return self._perform_request(request, _parse_base_properties) 736 737 def get_container_acl(self, container_name, lease_id=None, timeout=None): 738 ''' 739 Gets the permissions for the specified container. 740 The permissions indicate whether container data may be accessed publicly. 741 742 :param str container_name: 743 Name of existing container. 744 :param lease_id: 745 If specified, get_container_acl only succeeds if the 746 container's lease is active and matches this ID. 747 :param int timeout: 748 The timeout parameter is expressed in seconds. 749 :return: A dictionary of access policies associated with the container. dict of str to 750 :class:`azure.storage.common.models.AccessPolicy` and a public_access property 751 if public access is turned on 752 ''' 753 _validate_not_none('container_name', container_name) 754 request = HTTPRequest() 755 request.method = 'GET' 756 request.host_locations = self._get_host_locations(secondary=True) 757 request.path = _get_path(container_name) 758 request.query = { 759 'restype': 'container', 760 'comp': 'acl', 761 'timeout': _int_to_str(timeout), 762 } 763 request.headers = {'x-ms-lease-id': _to_str(lease_id)} 764 765 return self._perform_request(request, _convert_xml_to_signed_identifiers_and_access) 766 767 def set_container_acl(self, container_name, signed_identifiers=None, 768 public_access=None, lease_id=None, 769 if_modified_since=None, if_unmodified_since=None, timeout=None): 770 ''' 771 Sets the permissions for the specified container or stored access 772 policies that may be used with Shared Access Signatures. The permissions 773 indicate whether blobs in a container may be accessed publicly. 774 775 :param str container_name: 776 Name of existing container. 777 :param signed_identifiers: 778 A dictionary of access policies to associate with the container. The 779 dictionary may contain up to 5 elements. An empty dictionary 780 will clear the access policies set on the service. 781 :type signed_identifiers: dict(str, :class:`~azure.storage.common.models.AccessPolicy`) 782 :param ~azure.storage.blob.models.PublicAccess public_access: 783 Possible values include: container, blob. 784 :param str lease_id: 785 If specified, set_container_acl only succeeds if the 786 container's lease is active and matches this ID. 787 :param datetime if_modified_since: 788 A datetime value. Azure expects the date value passed in to be UTC. 789 If timezone is included, any non-UTC datetimes will be converted to UTC. 790 If a date is passed in without timezone info, it is assumed to be UTC. 791 Specify this header to perform the operation only 792 if the resource has been modified since the specified date/time. 793 :param datetime if_unmodified_since: 794 A datetime value. Azure expects the date value passed in to be UTC. 795 If timezone is included, any non-UTC datetimes will be converted to UTC. 796 If a date is passed in without timezone info, it is assumed to be UTC. 797 Specify this header to perform the operation only if 798 the resource has not been modified since the specified date/time. 799 :param int timeout: 800 The timeout parameter is expressed in seconds. 801 :return: ETag and last modified properties for the updated Container 802 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 803 ''' 804 _validate_not_none('container_name', container_name) 805 _validate_access_policies(signed_identifiers) 806 request = HTTPRequest() 807 request.method = 'PUT' 808 request.host_locations = self._get_host_locations() 809 request.path = _get_path(container_name) 810 request.query = { 811 'restype': 'container', 812 'comp': 'acl', 813 'timeout': _int_to_str(timeout), 814 } 815 request.headers = { 816 'x-ms-blob-public-access': _to_str(public_access), 817 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 818 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 819 'x-ms-lease-id': _to_str(lease_id), 820 } 821 request.body = _get_request_body( 822 _convert_signed_identifiers_to_xml(signed_identifiers)) 823 824 return self._perform_request(request, _parse_base_properties) 825 826 def delete_container(self, container_name, fail_not_exist=False, 827 lease_id=None, if_modified_since=None, 828 if_unmodified_since=None, timeout=None): 829 ''' 830 Marks the specified container for deletion. The container and any blobs 831 contained within it are later deleted during garbage collection. 832 833 :param str container_name: 834 Name of container to delete. 835 :param bool fail_not_exist: 836 Specify whether to throw an exception when the container doesn't 837 exist. 838 :param str lease_id: 839 If specified, delete_container only succeeds if the 840 container's lease is active and matches this ID. 841 Required if the container has an active lease. 842 :param datetime if_modified_since: 843 A DateTime value. Azure expects the date value passed in to be UTC. 844 If timezone is included, any non-UTC datetimes will be converted to UTC. 845 If a date is passed in without timezone info, it is assumed to be UTC. 846 Specify this header to perform the operation only 847 if the resource has been modified since the specified time. 848 :param datetime if_unmodified_since: 849 A DateTime value. Azure expects the date value passed in to be UTC. 850 If timezone is included, any non-UTC datetimes will be converted to UTC. 851 If a date is passed in without timezone info, it is assumed to be UTC. 852 Specify this header to perform the operation only if 853 the resource has not been modified since the specified date/time. 854 :param int timeout: 855 The timeout parameter is expressed in seconds. 856 :return: True if container is deleted, False container doesn't exist. 857 :rtype: bool 858 ''' 859 _validate_not_none('container_name', container_name) 860 request = HTTPRequest() 861 request.method = 'DELETE' 862 request.host_locations = self._get_host_locations() 863 request.path = _get_path(container_name) 864 request.query = { 865 'restype': 'container', 866 'timeout': _int_to_str(timeout), 867 } 868 request.headers = { 869 'x-ms-lease-id': _to_str(lease_id), 870 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 871 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 872 } 873 874 if not fail_not_exist: 875 try: 876 self._perform_request(request) 877 return True 878 except AzureHttpError as ex: 879 _dont_fail_not_exist(ex) 880 return False 881 else: 882 self._perform_request(request) 883 return True 884 885 def _lease_container_impl( 886 self, container_name, lease_action, lease_id, lease_duration, 887 lease_break_period, proposed_lease_id, if_modified_since, 888 if_unmodified_since, timeout): 889 ''' 890 Establishes and manages a lease on a container. 891 The Lease Container operation can be called in one of five modes 892 Acquire, to request a new lease 893 Renew, to renew an existing lease 894 Change, to change the ID of an existing lease 895 Release, to free the lease if it is no longer needed so that another 896 client may immediately acquire a lease against the container 897 Break, to end the lease but ensure that another client cannot acquire 898 a new lease until the current lease period has expired 899 900 :param str container_name: 901 Name of existing container. 902 :param str lease_action: 903 Possible _LeaseActions values: acquire|renew|release|break|change 904 :param str lease_id: 905 Required if the container has an active lease. 906 :param int lease_duration: 907 Specifies the duration of the lease, in seconds, or negative one 908 (-1) for a lease that never expires. A non-infinite lease can be 909 between 15 and 60 seconds. A lease duration cannot be changed 910 using renew or change. For backwards compatibility, the default is 911 60, and the value is only used on an acquire operation. 912 :param int lease_break_period: 913 For a break operation, this is the proposed duration of 914 seconds that the lease should continue before it is broken, between 915 0 and 60 seconds. This break period is only used if it is shorter 916 than the time remaining on the lease. If longer, the time remaining 917 on the lease is used. A new lease will not be available before the 918 break period has expired, but the lease may be held for longer than 919 the break period. If this header does not appear with a break 920 operation, a fixed-duration lease breaks after the remaining lease 921 period elapses, and an infinite lease breaks immediately. 922 :param str proposed_lease_id: 923 Optional for Acquire, required for Change. Proposed lease ID, in a 924 GUID string format. The Blob service returns 400 (Invalid request) 925 if the proposed lease ID is not in the correct format. 926 :param datetime if_modified_since: 927 A DateTime value. Azure expects the date value passed in to be UTC. 928 If timezone is included, any non-UTC datetimes will be converted to UTC. 929 If a date is passed in without timezone info, it is assumed to be UTC. 930 Specify this header to perform the operation only 931 if the resource has been modified since the specified time. 932 :param datetime if_unmodified_since: 933 A DateTime value. Azure expects the date value passed in to be UTC. 934 If timezone is included, any non-UTC datetimes will be converted to UTC. 935 If a date is passed in without timezone info, it is assumed to be UTC. 936 Specify this header to perform the operation only if 937 the resource has not been modified since the specified date/time. 938 :param int timeout: 939 The timeout parameter is expressed in seconds. 940 :return: 941 Response headers returned from the service call. 942 :rtype: dict(str, str) 943 ''' 944 _validate_not_none('container_name', container_name) 945 _validate_not_none('lease_action', lease_action) 946 request = HTTPRequest() 947 request.method = 'PUT' 948 request.host_locations = self._get_host_locations() 949 request.path = _get_path(container_name) 950 request.query = { 951 'restype': 'container', 952 'comp': 'lease', 953 'timeout': _int_to_str(timeout), 954 } 955 request.headers = { 956 'x-ms-lease-id': _to_str(lease_id), 957 'x-ms-lease-action': _to_str(lease_action), 958 'x-ms-lease-duration': _to_str(lease_duration), 959 'x-ms-lease-break-period': _to_str(lease_break_period), 960 'x-ms-proposed-lease-id': _to_str(proposed_lease_id), 961 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 962 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 963 } 964 965 return self._perform_request(request, _parse_lease) 966 967 def acquire_container_lease( 968 self, container_name, lease_duration=-1, proposed_lease_id=None, 969 if_modified_since=None, if_unmodified_since=None, timeout=None): 970 ''' 971 Requests a new lease. If the container does not have an active lease, 972 the Blob service creates a lease on the container and returns a new 973 lease ID. 974 975 :param str container_name: 976 Name of existing container. 977 :param int lease_duration: 978 Specifies the duration of the lease, in seconds, or negative one 979 (-1) for a lease that never expires. A non-infinite lease can be 980 between 15 and 60 seconds. A lease duration cannot be changed 981 using renew or change. Default is -1 (infinite lease). 982 :param str proposed_lease_id: 983 Proposed lease ID, in a GUID string format. The Blob service returns 984 400 (Invalid request) if the proposed lease ID is not in the correct format. 985 :param datetime if_modified_since: 986 A DateTime value. Azure expects the date value passed in to be UTC. 987 If timezone is included, any non-UTC datetimes will be converted to UTC. 988 If a date is passed in without timezone info, it is assumed to be UTC. 989 Specify this header to perform the operation only 990 if the resource has been modified since the specified time. 991 :param datetime if_unmodified_since: 992 A DateTime value. Azure expects the date value passed in to be UTC. 993 If timezone is included, any non-UTC datetimes will be converted to UTC. 994 If a date is passed in without timezone info, it is assumed to be UTC. 995 Specify this header to perform the operation only if 996 the resource has not been modified since the specified date/time. 997 :param int timeout: 998 The timeout parameter is expressed in seconds. 999 :return: the lease ID of the newly created lease. 1000 :return: str 1001 ''' 1002 _validate_not_none('lease_duration', lease_duration) 1003 if lease_duration != -1 and \ 1004 (lease_duration < 15 or lease_duration > 60): 1005 raise ValueError(_ERROR_INVALID_LEASE_DURATION) 1006 1007 lease = self._lease_container_impl(container_name, 1008 _LeaseActions.Acquire, 1009 None, # lease_id 1010 lease_duration, 1011 None, # lease_break_period 1012 proposed_lease_id, 1013 if_modified_since, 1014 if_unmodified_since, 1015 timeout) 1016 return lease['id'] 1017 1018 def renew_container_lease( 1019 self, container_name, lease_id, if_modified_since=None, 1020 if_unmodified_since=None, timeout=None): 1021 ''' 1022 Renews the lease. The lease can be renewed if the lease ID specified 1023 matches that associated with the container. Note that 1024 the lease may be renewed even if it has expired as long as the container 1025 has not been leased again since the expiration of that lease. When you 1026 renew a lease, the lease duration clock resets. 1027 1028 :param str container_name: 1029 Name of existing container. 1030 :param str lease_id: 1031 Lease ID for active lease. 1032 :param datetime if_modified_since: 1033 A DateTime value. Azure expects the date value passed in to be UTC. 1034 If timezone is included, any non-UTC datetimes will be converted to UTC. 1035 If a date is passed in without timezone info, it is assumed to be UTC. 1036 Specify this header to perform the operation only 1037 if the resource has been modified since the specified time. 1038 :param datetime if_unmodified_since: 1039 A DateTime value. Azure expects the date value passed in to be UTC. 1040 If timezone is included, any non-UTC datetimes will be converted to UTC. 1041 If a date is passed in without timezone info, it is assumed to be UTC. 1042 Specify this header to perform the operation only if 1043 the resource has not been modified since the specified date/time. 1044 :param int timeout: 1045 The timeout parameter is expressed in seconds. 1046 :return: the lease ID of the renewed lease. 1047 :return: str 1048 ''' 1049 _validate_not_none('lease_id', lease_id) 1050 1051 lease = self._lease_container_impl(container_name, 1052 _LeaseActions.Renew, 1053 lease_id, 1054 None, # lease_duration 1055 None, # lease_break_period 1056 None, # proposed_lease_id 1057 if_modified_since, 1058 if_unmodified_since, 1059 timeout) 1060 return lease['id'] 1061 1062 def release_container_lease( 1063 self, container_name, lease_id, if_modified_since=None, 1064 if_unmodified_since=None, timeout=None): 1065 ''' 1066 Release the lease. The lease may be released if the lease_id specified matches 1067 that associated with the container. Releasing the lease allows another client 1068 to immediately acquire the lease for the container as soon as the release is complete. 1069 1070 :param str container_name: 1071 Name of existing container. 1072 :param str lease_id: 1073 Lease ID for active lease. 1074 :param datetime if_modified_since: 1075 A DateTime value. Azure expects the date value passed in to be UTC. 1076 If timezone is included, any non-UTC datetimes will be converted to UTC. 1077 If a date is passed in without timezone info, it is assumed to be UTC. 1078 Specify this header to perform the operation only 1079 if the resource has been modified since the specified time. 1080 :param datetime if_unmodified_since: 1081 A DateTime value. Azure expects the date value passed in to be UTC. 1082 If timezone is included, any non-UTC datetimes will be converted to UTC. 1083 If a date is passed in without timezone info, it is assumed to be UTC. 1084 Specify this header to perform the operation only if 1085 the resource has not been modified since the specified date/time. 1086 :param int timeout: 1087 The timeout parameter is expressed in seconds. 1088 ''' 1089 _validate_not_none('lease_id', lease_id) 1090 1091 self._lease_container_impl(container_name, 1092 _LeaseActions.Release, 1093 lease_id, 1094 None, # lease_duration 1095 None, # lease_break_period 1096 None, # proposed_lease_id 1097 if_modified_since, 1098 if_unmodified_since, 1099 timeout) 1100 1101 def break_container_lease( 1102 self, container_name, lease_break_period=None, 1103 if_modified_since=None, if_unmodified_since=None, timeout=None): 1104 ''' 1105 Break the lease, if the container has an active lease. Once a lease is 1106 broken, it cannot be renewed. Any authorized request can break the lease; 1107 the request is not required to specify a matching lease ID. When a lease 1108 is broken, the lease break period is allowed to elapse, during which time 1109 no lease operation except break and release can be performed on the container. 1110 When a lease is successfully broken, the response indicates the interval 1111 in seconds until a new lease can be acquired. 1112 1113 :param str container_name: 1114 Name of existing container. 1115 :param int lease_break_period: 1116 This is the proposed duration of seconds that the lease 1117 should continue before it is broken, between 0 and 60 seconds. This 1118 break period is only used if it is shorter than the time remaining 1119 on the lease. If longer, the time remaining on the lease is used. 1120 A new lease will not be available before the break period has 1121 expired, but the lease may be held for longer than the break 1122 period. If this header does not appear with a break 1123 operation, a fixed-duration lease breaks after the remaining lease 1124 period elapses, and an infinite lease breaks immediately. 1125 :param datetime if_modified_since: 1126 A DateTime value. Azure expects the date value passed in to be UTC. 1127 If timezone is included, any non-UTC datetimes will be converted to UTC. 1128 If a date is passed in without timezone info, it is assumed to be UTC. 1129 Specify this header to perform the operation only 1130 if the resource has been modified since the specified time. 1131 :param datetime if_unmodified_since: 1132 A DateTime value. Azure expects the date value passed in to be UTC. 1133 If timezone is included, any non-UTC datetimes will be converted to UTC. 1134 If a date is passed in without timezone info, it is assumed to be UTC. 1135 Specify this header to perform the operation only if 1136 the resource has not been modified since the specified date/time. 1137 :param int timeout: 1138 The timeout parameter is expressed in seconds. 1139 :return: Approximate time remaining in the lease period, in seconds. 1140 :return: int 1141 ''' 1142 if (lease_break_period is not None) and (lease_break_period < 0 or lease_break_period > 60): 1143 raise ValueError(_ERROR_INVALID_LEASE_BREAK_PERIOD) 1144 1145 lease = self._lease_container_impl(container_name, 1146 _LeaseActions.Break, 1147 None, # lease_id 1148 None, # lease_duration 1149 lease_break_period, 1150 None, # proposed_lease_id 1151 if_modified_since, 1152 if_unmodified_since, 1153 timeout) 1154 return lease['time'] 1155 1156 def change_container_lease( 1157 self, container_name, lease_id, proposed_lease_id, 1158 if_modified_since=None, if_unmodified_since=None, timeout=None): 1159 ''' 1160 Change the lease ID of an active lease. A change must include the current 1161 lease ID and a new lease ID. 1162 1163 :param str container_name: 1164 Name of existing container. 1165 :param str lease_id: 1166 Lease ID for active lease. 1167 :param str proposed_lease_id: 1168 Proposed lease ID, in a GUID string format. The Blob service returns 400 1169 (Invalid request) if the proposed lease ID is not in the correct format. 1170 :param datetime if_modified_since: 1171 A DateTime value. Azure expects the date value passed in to be UTC. 1172 If timezone is included, any non-UTC datetimes will be converted to UTC. 1173 If a date is passed in without timezone info, it is assumed to be UTC. 1174 Specify this header to perform the operation only 1175 if the resource has been modified since the specified time. 1176 :param datetime if_unmodified_since: 1177 A DateTime value. Azure expects the date value passed in to be UTC. 1178 If timezone is included, any non-UTC datetimes will be converted to UTC. 1179 If a date is passed in without timezone info, it is assumed to be UTC. 1180 Specify this header to perform the operation only if 1181 the resource has not been modified since the specified date/time. 1182 :param int timeout: 1183 The timeout parameter is expressed in seconds. 1184 ''' 1185 _validate_not_none('lease_id', lease_id) 1186 1187 self._lease_container_impl(container_name, 1188 _LeaseActions.Change, 1189 lease_id, 1190 None, # lease_duration 1191 None, # lease_break_period 1192 proposed_lease_id, 1193 if_modified_since, 1194 if_unmodified_since, 1195 timeout) 1196 1197 def list_blobs(self, container_name, prefix=None, num_results=None, include=None, 1198 delimiter=None, marker=None, timeout=None): 1199 ''' 1200 Returns a generator to list the blobs under the specified container. 1201 The generator will lazily follow the continuation tokens returned by 1202 the service and stop when all blobs have been returned or num_results is reached. 1203 1204 If num_results is specified and the account has more than that number of 1205 blobs, the generator will have a populated next_marker field once it 1206 finishes. This marker can be used to create a new generator if more 1207 results are desired. 1208 1209 :param str container_name: 1210 Name of existing container. 1211 :param str prefix: 1212 Filters the results to return only blobs whose names 1213 begin with the specified prefix. 1214 :param int num_results: 1215 Specifies the maximum number of blobs to return, 1216 including all :class:`BlobPrefix` elements. If the request does not specify 1217 num_results or specifies a value greater than 5,000, the server will 1218 return up to 5,000 items. Setting num_results to a value less than 1219 or equal to zero results in error response code 400 (Bad Request). 1220 :param ~azure.storage.blob.models.Include include: 1221 Specifies one or more additional datasets to include in the response. 1222 :param str delimiter: 1223 When the request includes this parameter, the operation 1224 returns a :class:`~azure.storage.blob.models.BlobPrefix` element in the 1225 result list that acts as a placeholder for all blobs whose names begin 1226 with the same substring up to the appearance of the delimiter character. 1227 The delimiter may be a single character or a string. 1228 :param str marker: 1229 An opaque continuation token. This value can be retrieved from the 1230 next_marker field of a previous generator object if num_results was 1231 specified and that generator has finished enumerating results. If 1232 specified, this generator will begin returning results from the point 1233 where the previous generator stopped. 1234 :param int timeout: 1235 The timeout parameter is expressed in seconds. 1236 ''' 1237 operation_context = _OperationContext(location_lock=True) 1238 args = (container_name,) 1239 kwargs = {'prefix': prefix, 'marker': marker, 'max_results': num_results, 1240 'include': include, 'delimiter': delimiter, 'timeout': timeout, 1241 '_context': operation_context} 1242 resp = self._list_blobs(*args, **kwargs) 1243 1244 return ListGenerator(resp, self._list_blobs, args, kwargs) 1245 1246 def _list_blobs(self, container_name, prefix=None, marker=None, 1247 max_results=None, include=None, delimiter=None, timeout=None, 1248 _context=None): 1249 ''' 1250 Returns the list of blobs under the specified container. 1251 1252 :param str container_name: 1253 Name of existing container. 1254 :parm str prefix: 1255 Filters the results to return only blobs whose names 1256 begin with the specified prefix. 1257 :param str marker: 1258 A string value that identifies the portion of the list 1259 to be returned with the next list operation. The operation returns 1260 a next_marker value within the response body if the list returned was 1261 not complete. The marker value may then be used in a subsequent 1262 call to request the next set of list items. The marker value is 1263 opaque to the client. 1264 :param int max_results: 1265 Specifies the maximum number of blobs to return, 1266 including all :class:`~azure.storage.blob.models.BlobPrefix` elements. If the request does not specify 1267 max_results or specifies a value greater than 5,000, the server will 1268 return up to 5,000 items. Setting max_results to a value less than 1269 or equal to zero results in error response code 400 (Bad Request). 1270 :param str include: 1271 Specifies one or more datasets to include in the 1272 response. To specify more than one of these options on the URI, 1273 you must separate each option with a comma. Valid values are: 1274 snapshots: 1275 Specifies that snapshots should be included in the 1276 enumeration. Snapshots are listed from oldest to newest in 1277 the response. 1278 metadata: 1279 Specifies that blob metadata be returned in the response. 1280 uncommittedblobs: 1281 Specifies that blobs for which blocks have been uploaded, 1282 but which have not been committed using Put Block List 1283 (REST API), be included in the response. 1284 copy: 1285 Version 2012-02-12 and newer. Specifies that metadata 1286 related to any current or previous Copy Blob operation 1287 should be included in the response. 1288 deleted: 1289 Version 2017-07-29 and newer. Specifies that soft deleted blobs 1290 which are retained by the service should be included 1291 in the response. 1292 :param str delimiter: 1293 When the request includes this parameter, the operation 1294 returns a :class:`~azure.storage.blob.models.BlobPrefix` element in the response body that acts as a 1295 placeholder for all blobs whose names begin with the same 1296 substring up to the appearance of the delimiter character. The 1297 delimiter may be a single character or a string. 1298 :param int timeout: 1299 The timeout parameter is expressed in seconds. 1300 ''' 1301 _validate_not_none('container_name', container_name) 1302 request = HTTPRequest() 1303 request.method = 'GET' 1304 request.host_locations = self._get_host_locations(secondary=True) 1305 request.path = _get_path(container_name) 1306 request.query = { 1307 'restype': 'container', 1308 'comp': 'list', 1309 'prefix': _to_str(prefix), 1310 'delimiter': _to_str(delimiter), 1311 'marker': _to_str(marker), 1312 'maxresults': _int_to_str(max_results), 1313 'include': _to_str(include), 1314 'timeout': _int_to_str(timeout), 1315 } 1316 1317 return self._perform_request(request, _convert_xml_to_blob_list, operation_context=_context) 1318 1319 def get_blob_service_stats(self, timeout=None): 1320 ''' 1321 Retrieves statistics related to replication for the Blob service. It is 1322 only available when read-access geo-redundant replication is enabled for 1323 the storage account. 1324 1325 With geo-redundant replication, Azure Storage maintains your data durable 1326 in two locations. In both locations, Azure Storage constantly maintains 1327 multiple healthy replicas of your data. The location where you read, 1328 create, update, or delete data is the primary storage account location. 1329 The primary location exists in the region you choose at the time you 1330 create an account via the Azure Management Azure classic portal, for 1331 example, North Central US. The location to which your data is replicated 1332 is the secondary location. The secondary location is automatically 1333 determined based on the location of the primary; it is in a second data 1334 center that resides in the same region as the primary location. Read-only 1335 access is available from the secondary location, if read-access geo-redundant 1336 replication is enabled for your storage account. 1337 1338 :param int timeout: 1339 The timeout parameter is expressed in seconds. 1340 :return: The blob service stats. 1341 :rtype: :class:`~azure.storage.common.models.ServiceStats` 1342 ''' 1343 request = HTTPRequest() 1344 request.method = 'GET' 1345 request.host_locations = self._get_host_locations(primary=False, secondary=True) 1346 request.path = _get_path() 1347 request.query = { 1348 'restype': 'service', 1349 'comp': 'stats', 1350 'timeout': _int_to_str(timeout), 1351 } 1352 1353 return self._perform_request(request, _convert_xml_to_service_stats) 1354 1355 def set_blob_service_properties( 1356 self, logging=None, hour_metrics=None, minute_metrics=None, 1357 cors=None, target_version=None, timeout=None, delete_retention_policy=None): 1358 ''' 1359 Sets the properties of a storage account's Blob service, including 1360 Azure Storage Analytics. If an element (ex Logging) is left as None, the 1361 existing settings on the service for that functionality are preserved. 1362 1363 :param logging: 1364 Groups the Azure Analytics Logging settings. 1365 :type logging: 1366 :class:`~azure.storage.common.models.Logging` 1367 :param hour_metrics: 1368 The hour metrics settings provide a summary of request 1369 statistics grouped by API in hourly aggregates for blobs. 1370 :type hour_metrics: 1371 :class:`~azure.storage.common.models.Metrics` 1372 :param minute_metrics: 1373 The minute metrics settings provide request statistics 1374 for each minute for blobs. 1375 :type minute_metrics: 1376 :class:`~azure.storage.common.models.Metrics` 1377 :param cors: 1378 You can include up to five CorsRule elements in the 1379 list. If an empty list is specified, all CORS rules will be deleted, 1380 and CORS will be disabled for the service. 1381 :type cors: list(:class:`~azure.storage.common.models.CorsRule`) 1382 :param str target_version: 1383 Indicates the default version to use for requests if an incoming 1384 request's version is not specified. 1385 :param int timeout: 1386 The timeout parameter is expressed in seconds. 1387 :param delete_retention_policy: 1388 The delete retention policy specifies whether to retain deleted blobs. 1389 It also specifies the number of days and versions of blob to keep. 1390 :type delete_retention_policy: 1391 :class:`~azure.storage.common.models.DeleteRetentionPolicy` 1392 ''' 1393 request = HTTPRequest() 1394 request.method = 'PUT' 1395 request.host_locations = self._get_host_locations() 1396 request.path = _get_path() 1397 request.query = { 1398 'restype': 'service', 1399 'comp': 'properties', 1400 'timeout': _int_to_str(timeout), 1401 } 1402 request.body = _get_request_body( 1403 _convert_service_properties_to_xml(logging, hour_metrics, minute_metrics, 1404 cors, target_version, delete_retention_policy)) 1405 1406 self._perform_request(request) 1407 1408 def get_blob_service_properties(self, timeout=None): 1409 ''' 1410 Gets the properties of a storage account's Blob service, including 1411 Azure Storage Analytics. 1412 1413 :param int timeout: 1414 The timeout parameter is expressed in seconds. 1415 :return: The blob :class:`~azure.storage.common.models.ServiceProperties` with an attached 1416 target_version property. 1417 ''' 1418 request = HTTPRequest() 1419 request.method = 'GET' 1420 request.host_locations = self._get_host_locations(secondary=True) 1421 request.path = _get_path() 1422 request.query = { 1423 'restype': 'service', 1424 'comp': 'properties', 1425 'timeout': _int_to_str(timeout), 1426 } 1427 1428 return self._perform_request(request, _convert_xml_to_service_properties) 1429 1430 def get_blob_properties( 1431 self, container_name, blob_name, snapshot=None, lease_id=None, 1432 if_modified_since=None, if_unmodified_since=None, if_match=None, 1433 if_none_match=None, timeout=None): 1434 ''' 1435 Returns all user-defined metadata, standard HTTP properties, and 1436 system properties for the blob. It does not return the content of the blob. 1437 Returns :class:`~azure.storage.blob.models.Blob` 1438 with :class:`~azure.storage.blob.models.BlobProperties` and a metadata dict. 1439 1440 :param str container_name: 1441 Name of existing container. 1442 :param str blob_name: 1443 Name of existing blob. 1444 :param str snapshot: 1445 The snapshot parameter is an opaque DateTime value that, 1446 when present, specifies the blob snapshot to retrieve. 1447 :param str lease_id: 1448 Required if the blob has an active lease. 1449 :param datetime if_modified_since: 1450 A DateTime value. Azure expects the date value passed in to be UTC. 1451 If timezone is included, any non-UTC datetimes will be converted to UTC. 1452 If a date is passed in without timezone info, it is assumed to be UTC. 1453 Specify this header to perform the operation only 1454 if the resource has been modified since the specified time. 1455 :param datetime if_unmodified_since: 1456 A DateTime value. Azure expects the date value passed in to be UTC. 1457 If timezone is included, any non-UTC datetimes will be converted to UTC. 1458 If a date is passed in without timezone info, it is assumed to be UTC. 1459 Specify this header to perform the operation only if 1460 the resource has not been modified since the specified date/time. 1461 :param str if_match: 1462 An ETag value, or the wildcard character (*). Specify this header to perform 1463 the operation only if the resource's ETag matches the value specified. 1464 :param str if_none_match: 1465 An ETag value, or the wildcard character (*). Specify this header 1466 to perform the operation only if the resource's ETag does not match 1467 the value specified. Specify the wildcard character (*) to perform 1468 the operation only if the resource does not exist, and fail the 1469 operation if it does exist. 1470 :param int timeout: 1471 The timeout parameter is expressed in seconds. 1472 :return: a blob object including properties and metadata. 1473 :rtype: :class:`~azure.storage.blob.models.Blob` 1474 ''' 1475 _validate_not_none('container_name', container_name) 1476 _validate_not_none('blob_name', blob_name) 1477 request = HTTPRequest() 1478 request.method = 'HEAD' 1479 request.host_locations = self._get_host_locations(secondary=True) 1480 request.path = _get_path(container_name, blob_name) 1481 request.query = { 1482 'snapshot': _to_str(snapshot), 1483 'timeout': _int_to_str(timeout), 1484 } 1485 request.headers = { 1486 'x-ms-lease-id': _to_str(lease_id), 1487 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 1488 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 1489 'If-Match': _to_str(if_match), 1490 'If-None-Match': _to_str(if_none_match), 1491 } 1492 1493 return self._perform_request(request, _parse_blob, [blob_name, snapshot]) 1494 1495 def set_blob_properties( 1496 self, container_name, blob_name, content_settings=None, lease_id=None, 1497 if_modified_since=None, if_unmodified_since=None, if_match=None, 1498 if_none_match=None, timeout=None): 1499 ''' 1500 Sets system properties on the blob. If one property is set for the 1501 content_settings, all properties will be overriden. 1502 1503 :param str container_name: 1504 Name of existing container. 1505 :param str blob_name: 1506 Name of existing blob. 1507 :param ~azure.storage.blob.models.ContentSettings content_settings: 1508 ContentSettings object used to set blob properties. 1509 :param str lease_id: 1510 Required if the blob has an active lease. 1511 :param datetime if_modified_since: 1512 A DateTime value. Azure expects the date value passed in to be UTC. 1513 If timezone is included, any non-UTC datetimes will be converted to UTC. 1514 If a date is passed in without timezone info, it is assumed to be UTC. 1515 Specify this header to perform the operation only 1516 if the resource has been modified since the specified time. 1517 :param datetime if_unmodified_since: 1518 A DateTime value. Azure expects the date value passed in to be UTC. 1519 If timezone is included, any non-UTC datetimes will be converted to UTC. 1520 If a date is passed in without timezone info, it is assumed to be UTC. 1521 Specify this header to perform the operation only if 1522 the resource has not been modified since the specified date/time. 1523 :param str if_match: 1524 An ETag value, or the wildcard character (*). Specify this header to perform 1525 the operation only if the resource's ETag matches the value specified. 1526 :param str if_none_match: 1527 An ETag value, or the wildcard character (*). Specify this header 1528 to perform the operation only if the resource's ETag does not match 1529 the value specified. Specify the wildcard character (*) to perform 1530 the operation only if the resource does not exist, and fail the 1531 operation if it does exist. 1532 :param int timeout: 1533 The timeout parameter is expressed in seconds. 1534 :return: ETag and last modified properties for the updated Blob 1535 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 1536 ''' 1537 _validate_not_none('container_name', container_name) 1538 _validate_not_none('blob_name', blob_name) 1539 request = HTTPRequest() 1540 request.method = 'PUT' 1541 request.host_locations = self._get_host_locations() 1542 request.path = _get_path(container_name, blob_name) 1543 request.query = { 1544 'comp': 'properties', 1545 'timeout': _int_to_str(timeout), 1546 } 1547 request.headers = { 1548 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 1549 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 1550 'If-Match': _to_str(if_match), 1551 'If-None-Match': _to_str(if_none_match), 1552 'x-ms-lease-id': _to_str(lease_id) 1553 } 1554 if content_settings is not None: 1555 request.headers.update(content_settings._to_headers()) 1556 1557 return self._perform_request(request, _parse_base_properties) 1558 1559 def exists(self, container_name, blob_name=None, snapshot=None, timeout=None): 1560 ''' 1561 Returns a boolean indicating whether the container exists (if blob_name 1562 is None), or otherwise a boolean indicating whether the blob exists. 1563 1564 :param str container_name: 1565 Name of a container. 1566 :param str blob_name: 1567 Name of a blob. If None, the container will be checked for existence. 1568 :param str snapshot: 1569 The snapshot parameter is an opaque DateTime value that, 1570 when present, specifies the snapshot. 1571 :param int timeout: 1572 The timeout parameter is expressed in seconds. 1573 :return: A boolean indicating whether the resource exists. 1574 :rtype: bool 1575 ''' 1576 _validate_not_none('container_name', container_name) 1577 try: 1578 if blob_name is None: 1579 self.get_container_properties(container_name, timeout=timeout) 1580 else: 1581 self.get_blob_properties(container_name, blob_name, snapshot=snapshot, timeout=timeout) 1582 return True 1583 except AzureHttpError as ex: 1584 _dont_fail_not_exist(ex) 1585 return False 1586 1587 def _get_blob( 1588 self, container_name, blob_name, snapshot=None, start_range=None, 1589 end_range=None, validate_content=False, lease_id=None, if_modified_since=None, 1590 if_unmodified_since=None, if_match=None, if_none_match=None, timeout=None, 1591 _context=None): 1592 ''' 1593 Downloads a blob's content, metadata, and properties. You can also 1594 call this API to read a snapshot. You can specify a range if you don't 1595 need to download the blob in its entirety. If no range is specified, 1596 the full blob will be downloaded. 1597 1598 See get_blob_to_* for high level functions that handle the download 1599 of large blobs with automatic chunking and progress notifications. 1600 1601 :param str container_name: 1602 Name of existing container. 1603 :param str blob_name: 1604 Name of existing blob. 1605 :param str snapshot: 1606 The snapshot parameter is an opaque DateTime value that, 1607 when present, specifies the blob snapshot to retrieve. 1608 :param int start_range: 1609 Start of byte range to use for downloading a section of the blob. 1610 If no end_range is given, all bytes after the start_range will be downloaded. 1611 The start_range and end_range params are inclusive. 1612 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 1613 :param int end_range: 1614 End of byte range to use for downloading a section of the blob. 1615 If end_range is given, start_range must be provided. 1616 The start_range and end_range params are inclusive. 1617 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 1618 :param bool validate_content: 1619 When this is set to True and specified together with the Range header, 1620 the service returns the MD5 hash for the range, as long as the range 1621 is less than or equal to 4 MB in size. 1622 :param str lease_id: 1623 Required if the blob has an active lease. 1624 :param datetime if_modified_since: 1625 A DateTime value. Azure expects the date value passed in to be UTC. 1626 If timezone is included, any non-UTC datetimes will be converted to UTC. 1627 If a date is passed in without timezone info, it is assumed to be UTC. 1628 Specify this header to perform the operation only 1629 if the resource has been modified since the specified time. 1630 :param datetime if_unmodified_since: 1631 A DateTime value. Azure expects the date value passed in to be UTC. 1632 If timezone is included, any non-UTC datetimes will be converted to UTC. 1633 If a date is passed in without timezone info, it is assumed to be UTC. 1634 Specify this header to perform the operation only if 1635 the resource has not been modified since the specified date/time. 1636 :param str if_match: 1637 An ETag value, or the wildcard character (*). Specify this header to perform 1638 the operation only if the resource's ETag matches the value specified. 1639 :param str if_none_match: 1640 An ETag value, or the wildcard character (*). Specify this header 1641 to perform the operation only if the resource's ETag does not match 1642 the value specified. Specify the wildcard character (*) to perform 1643 the operation only if the resource does not exist, and fail the 1644 operation if it does exist. 1645 :param int timeout: 1646 The timeout parameter is expressed in seconds. 1647 :return: A Blob with content, properties, and metadata. 1648 :rtype: :class:`~azure.storage.blob.models.Blob` 1649 ''' 1650 _validate_not_none('container_name', container_name) 1651 _validate_not_none('blob_name', blob_name) 1652 _validate_decryption_required(self.require_encryption, 1653 self.key_encryption_key, 1654 self.key_resolver_function) 1655 1656 start_offset, end_offset = 0, 0 1657 if self.key_encryption_key is not None or self.key_resolver_function is not None: 1658 if start_range is not None: 1659 # Align the start of the range along a 16 byte block 1660 start_offset = start_range % 16 1661 start_range -= start_offset 1662 1663 # Include an extra 16 bytes for the IV if necessary 1664 # Because of the previous offsetting, start_range will always 1665 # be a multiple of 16. 1666 if start_range > 0: 1667 start_offset += 16 1668 start_range -= 16 1669 1670 if end_range is not None: 1671 # Align the end of the range along a 16 byte block 1672 end_offset = 15 - (end_range % 16) 1673 end_range += end_offset 1674 1675 request = HTTPRequest() 1676 request.method = 'GET' 1677 request.host_locations = self._get_host_locations(secondary=True) 1678 request.path = _get_path(container_name, blob_name) 1679 request.query = { 1680 'snapshot': _to_str(snapshot), 1681 'timeout': _int_to_str(timeout), 1682 } 1683 request.headers = { 1684 'x-ms-lease-id': _to_str(lease_id), 1685 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 1686 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 1687 'If-Match': _to_str(if_match), 1688 'If-None-Match': _to_str(if_none_match), 1689 } 1690 _validate_and_format_range_headers( 1691 request, 1692 start_range, 1693 end_range, 1694 start_range_required=False, 1695 end_range_required=False, 1696 check_content_md5=validate_content) 1697 1698 return self._perform_request(request, _parse_blob, 1699 [blob_name, snapshot, validate_content, self.require_encryption, 1700 self.key_encryption_key, self.key_resolver_function, 1701 start_offset, end_offset], 1702 operation_context=_context) 1703 1704 def get_blob_to_path( 1705 self, container_name, blob_name, file_path, open_mode='wb', 1706 snapshot=None, start_range=None, end_range=None, 1707 validate_content=False, progress_callback=None, 1708 max_connections=2, lease_id=None, if_modified_since=None, 1709 if_unmodified_since=None, if_match=None, if_none_match=None, 1710 timeout=None): 1711 ''' 1712 Downloads a blob to a file path, with automatic chunking and progress 1713 notifications. Returns an instance of :class:`~azure.storage.blob.models.Blob` with 1714 properties and metadata. 1715 1716 :param str container_name: 1717 Name of existing container. 1718 :param str blob_name: 1719 Name of existing blob. 1720 :param str file_path: 1721 Path of file to write out to. 1722 :param str open_mode: 1723 Mode to use when opening the file. Note that specifying append only 1724 open_mode prevents parallel download. So, max_connections must be set 1725 to 1 if this open_mode is used. 1726 :param str snapshot: 1727 The snapshot parameter is an opaque DateTime value that, 1728 when present, specifies the blob snapshot to retrieve. 1729 :param int start_range: 1730 Start of byte range to use for downloading a section of the blob. 1731 If no end_range is given, all bytes after the start_range will be downloaded. 1732 The start_range and end_range params are inclusive. 1733 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 1734 :param int end_range: 1735 End of byte range to use for downloading a section of the blob. 1736 If end_range is given, start_range must be provided. 1737 The start_range and end_range params are inclusive. 1738 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 1739 :param bool validate_content: 1740 If set to true, validates an MD5 hash for each retrieved portion of 1741 the blob. This is primarily valuable for detecting bitflips on the wire 1742 if using http instead of https as https (the default) will already 1743 validate. Note that the service will only return transactional MD5s 1744 for chunks 4MB or less so the first get request will be of size 1745 self.MAX_CHUNK_GET_SIZE instead of self.MAX_SINGLE_GET_SIZE. If 1746 self.MAX_CHUNK_GET_SIZE was set to greater than 4MB an error will be 1747 thrown. As computing the MD5 takes processing time and more requests 1748 will need to be done due to the reduced chunk size there may be some 1749 increase in latency. 1750 :param progress_callback: 1751 Callback for progress with signature function(current, total) 1752 where current is the number of bytes transfered so far, and total is 1753 the size of the blob if known. 1754 :type progress_callback: func(current, total) 1755 :param int max_connections: 1756 If set to 2 or greater, an initial get will be done for the first 1757 self.MAX_SINGLE_GET_SIZE bytes of the blob. If this is the entire blob, 1758 the method returns at this point. If it is not, it will download the 1759 remaining data parallel using the number of threads equal to 1760 max_connections. Each chunk will be of size self.MAX_CHUNK_GET_SIZE. 1761 If set to 1, a single large get request will be done. This is not 1762 generally recommended but available if very few threads should be 1763 used, network requests are very expensive, or a non-seekable stream 1764 prevents parallel download. This may also be useful if many blobs are 1765 expected to be empty as an extra request is required for empty blobs 1766 if max_connections is greater than 1. 1767 :param str lease_id: 1768 Required if the blob has an active lease. 1769 :param datetime if_modified_since: 1770 A DateTime value. Azure expects the date value passed in to be UTC. 1771 If timezone is included, any non-UTC datetimes will be converted to UTC. 1772 If a date is passed in without timezone info, it is assumed to be UTC. 1773 Specify this header to perform the operation only 1774 if the resource has been modified since the specified time. 1775 :param datetime if_unmodified_since: 1776 A DateTime value. Azure expects the date value passed in to be UTC. 1777 If timezone is included, any non-UTC datetimes will be converted to UTC. 1778 If a date is passed in without timezone info, it is assumed to be UTC. 1779 Specify this header to perform the operation only if 1780 the resource has not been modified since the specified date/time. 1781 :param str if_match: 1782 An ETag value, or the wildcard character (*). Specify this header to perform 1783 the operation only if the resource's ETag matches the value specified. 1784 :param str if_none_match: 1785 An ETag value, or the wildcard character (*). Specify this header 1786 to perform the operation only if the resource's ETag does not match 1787 the value specified. Specify the wildcard character (*) to perform 1788 the operation only if the resource does not exist, and fail the 1789 operation if it does exist. 1790 :param int timeout: 1791 The timeout parameter is expressed in seconds. This method may make 1792 multiple calls to the Azure service and the timeout will apply to 1793 each call individually. 1794 :return: A Blob with properties and metadata. If max_connections is greater 1795 than 1, the content_md5 (if set on the blob) will not be returned. If you 1796 require this value, either use get_blob_properties or set max_connections 1797 to 1. 1798 :rtype: :class:`~azure.storage.blob.models.Blob` 1799 ''' 1800 _validate_not_none('container_name', container_name) 1801 _validate_not_none('blob_name', blob_name) 1802 _validate_not_none('file_path', file_path) 1803 _validate_not_none('open_mode', open_mode) 1804 1805 if max_connections > 1 and 'a' in open_mode: 1806 raise ValueError(_ERROR_PARALLEL_NOT_SEEKABLE) 1807 1808 with open(file_path, open_mode) as stream: 1809 blob = self.get_blob_to_stream( 1810 container_name, 1811 blob_name, 1812 stream, 1813 snapshot, 1814 start_range, 1815 end_range, 1816 validate_content, 1817 progress_callback, 1818 max_connections, 1819 lease_id, 1820 if_modified_since, 1821 if_unmodified_since, 1822 if_match, 1823 if_none_match, 1824 timeout) 1825 1826 return blob 1827 1828 def get_blob_to_stream( 1829 self, container_name, blob_name, stream, snapshot=None, 1830 start_range=None, end_range=None, validate_content=False, 1831 progress_callback=None, max_connections=2, lease_id=None, 1832 if_modified_since=None, if_unmodified_since=None, if_match=None, 1833 if_none_match=None, timeout=None): 1834 1835 ''' 1836 Downloads a blob to a stream, with automatic chunking and progress 1837 notifications. Returns an instance of :class:`~azure.storage.blob.models.Blob` with 1838 properties and metadata. 1839 1840 :param str container_name: 1841 Name of existing container. 1842 :param str blob_name: 1843 Name of existing blob. 1844 :param io.IOBase stream: 1845 Opened stream to write to. 1846 :param str snapshot: 1847 The snapshot parameter is an opaque DateTime value that, 1848 when present, specifies the blob snapshot to retrieve. 1849 :param int start_range: 1850 Start of byte range to use for downloading a section of the blob. 1851 If no end_range is given, all bytes after the start_range will be downloaded. 1852 The start_range and end_range params are inclusive. 1853 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 1854 :param int end_range: 1855 End of byte range to use for downloading a section of the blob. 1856 If end_range is given, start_range must be provided. 1857 The start_range and end_range params are inclusive. 1858 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 1859 :param bool validate_content: 1860 If set to true, validates an MD5 hash for each retrieved portion of 1861 the blob. This is primarily valuable for detecting bitflips on the wire 1862 if using http instead of https as https (the default) will already 1863 validate. Note that the service will only return transactional MD5s 1864 for chunks 4MB or less so the first get request will be of size 1865 self.MAX_CHUNK_GET_SIZE instead of self.MAX_SINGLE_GET_SIZE. If 1866 self.MAX_CHUNK_GET_SIZE was set to greater than 4MB an error will be 1867 thrown. As computing the MD5 takes processing time and more requests 1868 will need to be done due to the reduced chunk size there may be some 1869 increase in latency. 1870 :param progress_callback: 1871 Callback for progress with signature function(current, total) 1872 where current is the number of bytes transfered so far, and total is 1873 the size of the blob if known. 1874 :type progress_callback: func(current, total) 1875 :param int max_connections: 1876 If set to 2 or greater, an initial get will be done for the first 1877 self.MAX_SINGLE_GET_SIZE bytes of the blob. If this is the entire blob, 1878 the method returns at this point. If it is not, it will download the 1879 remaining data parallel using the number of threads equal to 1880 max_connections. Each chunk will be of size self.MAX_CHUNK_GET_SIZE. 1881 If set to 1, a single large get request will be done. This is not 1882 generally recommended but available if very few threads should be 1883 used, network requests are very expensive, or a non-seekable stream 1884 prevents parallel download. This may also be useful if many blobs are 1885 expected to be empty as an extra request is required for empty blobs 1886 if max_connections is greater than 1. 1887 :param str lease_id: 1888 Required if the blob has an active lease. 1889 :param datetime if_modified_since: 1890 A DateTime value. Azure expects the date value passed in to be UTC. 1891 If timezone is included, any non-UTC datetimes will be converted to UTC. 1892 If a date is passed in without timezone info, it is assumed to be UTC. 1893 Specify this header to perform the operation only 1894 if the resource has been modified since the specified time. 1895 :param datetime if_unmodified_since: 1896 A DateTime value. Azure expects the date value passed in to be UTC. 1897 If timezone is included, any non-UTC datetimes will be converted to UTC. 1898 If a date is passed in without timezone info, it is assumed to be UTC. 1899 Specify this header to perform the operation only if 1900 the resource has not been modified since the specified date/time. 1901 :param str if_match: 1902 An ETag value, or the wildcard character (*). Specify this header to perform 1903 the operation only if the resource's ETag matches the value specified. 1904 :param str if_none_match: 1905 An ETag value, or the wildcard character (*). Specify this header 1906 to perform the operation only if the resource's ETag does not match 1907 the value specified. Specify the wildcard character (*) to perform 1908 the operation only if the resource does not exist, and fail the 1909 operation if it does exist. 1910 :param int timeout: 1911 The timeout parameter is expressed in seconds. This method may make 1912 multiple calls to the Azure service and the timeout will apply to 1913 each call individually. 1914 :return: A Blob with properties and metadata. If max_connections is greater 1915 than 1, the content_md5 (if set on the blob) will not be returned. If you 1916 require this value, either use get_blob_properties or set max_connections 1917 to 1. 1918 :rtype: :class:`~azure.storage.blob.models.Blob` 1919 ''' 1920 _validate_not_none('container_name', container_name) 1921 _validate_not_none('blob_name', blob_name) 1922 _validate_not_none('stream', stream) 1923 1924 if end_range is not None: 1925 _validate_not_none("start_range", start_range) 1926 1927 # If the user explicitly sets max_connections to 1, do a single shot download 1928 if max_connections == 1: 1929 blob = self._get_blob(container_name, 1930 blob_name, 1931 snapshot, 1932 start_range=start_range, 1933 end_range=end_range, 1934 validate_content=validate_content, 1935 lease_id=lease_id, 1936 if_modified_since=if_modified_since, 1937 if_unmodified_since=if_unmodified_since, 1938 if_match=if_match, 1939 if_none_match=if_none_match, 1940 timeout=timeout) 1941 1942 # Set the download size 1943 download_size = blob.properties.content_length 1944 1945 # If max_connections is greater than 1, do the first get to establish the 1946 # size of the blob and get the first segment of data 1947 else: 1948 if sys.version_info >= (3,) and not stream.seekable(): 1949 raise ValueError(_ERROR_PARALLEL_NOT_SEEKABLE) 1950 1951 # The service only provides transactional MD5s for chunks under 4MB. 1952 # If validate_content is on, get only self.MAX_CHUNK_GET_SIZE for the first 1953 # chunk so a transactional MD5 can be retrieved. 1954 first_get_size = self.MAX_SINGLE_GET_SIZE if not validate_content else self.MAX_CHUNK_GET_SIZE 1955 1956 initial_request_start = start_range if start_range is not None else 0 1957 1958 if end_range is not None and end_range - start_range < first_get_size: 1959 initial_request_end = end_range 1960 else: 1961 initial_request_end = initial_request_start + first_get_size - 1 1962 1963 # Send a context object to make sure we always retry to the initial location 1964 operation_context = _OperationContext(location_lock=True) 1965 try: 1966 blob = self._get_blob(container_name, 1967 blob_name, 1968 snapshot, 1969 start_range=initial_request_start, 1970 end_range=initial_request_end, 1971 validate_content=validate_content, 1972 lease_id=lease_id, 1973 if_modified_since=if_modified_since, 1974 if_unmodified_since=if_unmodified_since, 1975 if_match=if_match, 1976 if_none_match=if_none_match, 1977 timeout=timeout, 1978 _context=operation_context) 1979 1980 # Parse the total blob size and adjust the download size if ranges 1981 # were specified 1982 blob_size = _parse_length_from_content_range(blob.properties.content_range) 1983 if end_range is not None: 1984 # Use the end_range unless it is over the end of the blob 1985 download_size = min(blob_size, end_range - start_range + 1) 1986 elif start_range is not None: 1987 download_size = blob_size - start_range 1988 else: 1989 download_size = blob_size 1990 except AzureHttpError as ex: 1991 if start_range is None and ex.status_code == 416: 1992 # Get range will fail on an empty blob. If the user did not 1993 # request a range, do a regular get request in order to get 1994 # any properties. 1995 blob = self._get_blob(container_name, 1996 blob_name, 1997 snapshot, 1998 validate_content=validate_content, 1999 lease_id=lease_id, 2000 if_modified_since=if_modified_since, 2001 if_unmodified_since=if_unmodified_since, 2002 if_match=if_match, 2003 if_none_match=if_none_match, 2004 timeout=timeout, 2005 _context=operation_context) 2006 2007 # Set the download size to empty 2008 download_size = 0 2009 else: 2010 raise ex 2011 2012 # Mark the first progress chunk. If the blob is small or this is a single 2013 # shot download, this is the only call 2014 if progress_callback: 2015 progress_callback(blob.properties.content_length, download_size) 2016 2017 # Write the content to the user stream 2018 # Clear blob content since output has been written to user stream 2019 if blob.content is not None: 2020 stream.write(blob.content) 2021 blob.content = None 2022 2023 # If the blob is small or single shot download was used, the download is 2024 # complete at this point. If blob size is large, use parallel download. 2025 if blob.properties.content_length != download_size: 2026 # Lock on the etag. This can be overriden by the user by specifying '*' 2027 if_match = if_match if if_match is not None else blob.properties.etag 2028 2029 end_blob = blob_size 2030 if end_range is not None: 2031 # Use the end_range unless it is over the end of the blob 2032 end_blob = min(blob_size, end_range + 1) 2033 2034 _download_blob_chunks( 2035 self, 2036 container_name, 2037 blob_name, 2038 snapshot, 2039 download_size, 2040 self.MAX_CHUNK_GET_SIZE, 2041 first_get_size, 2042 initial_request_end + 1, # start where the first download ended 2043 end_blob, 2044 stream, 2045 max_connections, 2046 progress_callback, 2047 validate_content, 2048 lease_id, 2049 if_modified_since, 2050 if_unmodified_since, 2051 if_match, 2052 if_none_match, 2053 timeout, 2054 operation_context 2055 ) 2056 2057 # Set the content length to the download size instead of the size of 2058 # the last range 2059 blob.properties.content_length = download_size 2060 2061 # Overwrite the content range to the user requested range 2062 blob.properties.content_range = 'bytes {0}-{1}/{2}'.format(start_range, end_range, blob_size) 2063 2064 # Overwrite the content MD5 as it is the MD5 for the last range instead 2065 # of the stored MD5 2066 # TODO: Set to the stored MD5 when the service returns this 2067 blob.properties.content_md5 = None 2068 2069 return blob 2070 2071 def get_blob_to_bytes( 2072 self, container_name, blob_name, snapshot=None, 2073 start_range=None, end_range=None, validate_content=False, 2074 progress_callback=None, max_connections=2, lease_id=None, 2075 if_modified_since=None, if_unmodified_since=None, if_match=None, 2076 if_none_match=None, timeout=None): 2077 ''' 2078 Downloads a blob as an array of bytes, with automatic chunking and 2079 progress notifications. Returns an instance of :class:`~azure.storage.blob.models.Blob` with 2080 properties, metadata, and content. 2081 2082 :param str container_name: 2083 Name of existing container. 2084 :param str blob_name: 2085 Name of existing blob. 2086 :param str snapshot: 2087 The snapshot parameter is an opaque DateTime value that, 2088 when present, specifies the blob snapshot to retrieve. 2089 :param int start_range: 2090 Start of byte range to use for downloading a section of the blob. 2091 If no end_range is given, all bytes after the start_range will be downloaded. 2092 The start_range and end_range params are inclusive. 2093 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 2094 :param int end_range: 2095 End of byte range to use for downloading a section of the blob. 2096 If end_range is given, start_range must be provided. 2097 The start_range and end_range params are inclusive. 2098 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 2099 :param bool validate_content: 2100 If set to true, validates an MD5 hash for each retrieved portion of 2101 the blob. This is primarily valuable for detecting bitflips on the wire 2102 if using http instead of https as https (the default) will already 2103 validate. Note that the service will only return transactional MD5s 2104 for chunks 4MB or less so the first get request will be of size 2105 self.MAX_CHUNK_GET_SIZE instead of self.MAX_SINGLE_GET_SIZE. If 2106 self.MAX_CHUNK_GET_SIZE was set to greater than 4MB an error will be 2107 thrown. As computing the MD5 takes processing time and more requests 2108 will need to be done due to the reduced chunk size there may be some 2109 increase in latency. 2110 :param progress_callback: 2111 Callback for progress with signature function(current, total) 2112 where current is the number of bytes transfered so far, and total is 2113 the size of the blob if known. 2114 :type progress_callback: func(current, total) 2115 :param int max_connections: 2116 If set to 2 or greater, an initial get will be done for the first 2117 self.MAX_SINGLE_GET_SIZE bytes of the blob. If this is the entire blob, 2118 the method returns at this point. If it is not, it will download the 2119 remaining data parallel using the number of threads equal to 2120 max_connections. Each chunk will be of size self.MAX_CHUNK_GET_SIZE. 2121 If set to 1, a single large get request will be done. This is not 2122 generally recommended but available if very few threads should be 2123 used, network requests are very expensive, or a non-seekable stream 2124 prevents parallel download. This may also be useful if many blobs are 2125 expected to be empty as an extra request is required for empty blobs 2126 if max_connections is greater than 1. 2127 :param str lease_id: 2128 Required if the blob has an active lease. 2129 :param datetime if_modified_since: 2130 A DateTime value. Azure expects the date value passed in to be UTC. 2131 If timezone is included, any non-UTC datetimes will be converted to UTC. 2132 If a date is passed in without timezone info, it is assumed to be UTC. 2133 Specify this header to perform the operation only 2134 if the resource has been modified since the specified time. 2135 :param datetime if_unmodified_since: 2136 A DateTime value. Azure expects the date value passed in to be UTC. 2137 If timezone is included, any non-UTC datetimes will be converted to UTC. 2138 If a date is passed in without timezone info, it is assumed to be UTC. 2139 Specify this header to perform the operation only if 2140 the resource has not been modified since the specified date/time. 2141 :param str if_match: 2142 An ETag value, or the wildcard character (*). Specify this header to perform 2143 the operation only if the resource's ETag matches the value specified. 2144 :param str if_none_match: 2145 An ETag value, or the wildcard character (*). Specify this header 2146 to perform the operation only if the resource's ETag does not match 2147 the value specified. Specify the wildcard character (*) to perform 2148 the operation only if the resource does not exist, and fail the 2149 operation if it does exist. 2150 :param int timeout: 2151 The timeout parameter is expressed in seconds. This method may make 2152 multiple calls to the Azure service and the timeout will apply to 2153 each call individually. 2154 :return: A Blob with properties and metadata. If max_connections is greater 2155 than 1, the content_md5 (if set on the blob) will not be returned. If you 2156 require this value, either use get_blob_properties or set max_connections 2157 to 1. 2158 :rtype: :class:`~azure.storage.blob.models.Blob` 2159 ''' 2160 _validate_not_none('container_name', container_name) 2161 _validate_not_none('blob_name', blob_name) 2162 2163 stream = BytesIO() 2164 blob = self.get_blob_to_stream( 2165 container_name, 2166 blob_name, 2167 stream, 2168 snapshot, 2169 start_range, 2170 end_range, 2171 validate_content, 2172 progress_callback, 2173 max_connections, 2174 lease_id, 2175 if_modified_since, 2176 if_unmodified_since, 2177 if_match, 2178 if_none_match, 2179 timeout) 2180 2181 blob.content = stream.getvalue() 2182 return blob 2183 2184 def get_blob_to_text( 2185 self, container_name, blob_name, encoding='utf-8', snapshot=None, 2186 start_range=None, end_range=None, validate_content=False, 2187 progress_callback=None, max_connections=2, lease_id=None, 2188 if_modified_since=None, if_unmodified_since=None, if_match=None, 2189 if_none_match=None, timeout=None): 2190 ''' 2191 Downloads a blob as unicode text, with automatic chunking and progress 2192 notifications. Returns an instance of :class:`~azure.storage.blob.models.Blob` with 2193 properties, metadata, and content. 2194 2195 :param str container_name: 2196 Name of existing container. 2197 :param str blob_name: 2198 Name of existing blob. 2199 :param str encoding: 2200 Python encoding to use when decoding the blob data. 2201 :param str snapshot: 2202 The snapshot parameter is an opaque DateTime value that, 2203 when present, specifies the blob snapshot to retrieve. 2204 :param int start_range: 2205 Start of byte range to use for downloading a section of the blob. 2206 If no end_range is given, all bytes after the start_range will be downloaded. 2207 The start_range and end_range params are inclusive. 2208 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 2209 :param int end_range: 2210 End of byte range to use for downloading a section of the blob. 2211 If end_range is given, start_range must be provided. 2212 The start_range and end_range params are inclusive. 2213 Ex: start_range=0, end_range=511 will download first 512 bytes of blob. 2214 :param bool validate_content: 2215 If set to true, validates an MD5 hash for each retrieved portion of 2216 the blob. This is primarily valuable for detecting bitflips on the wire 2217 if using http instead of https as https (the default) will already 2218 validate. Note that the service will only return transactional MD5s 2219 for chunks 4MB or less so the first get request will be of size 2220 self.MAX_CHUNK_GET_SIZE instead of self.MAX_SINGLE_GET_SIZE. If 2221 self.MAX_CHUNK_GET_SIZE was set to greater than 4MB an error will be 2222 thrown. As computing the MD5 takes processing time and more requests 2223 will need to be done due to the reduced chunk size there may be some 2224 increase in latency. 2225 :param progress_callback: 2226 Callback for progress with signature function(current, total) 2227 where current is the number of bytes transfered so far, and total is 2228 the size of the blob if known. 2229 :type progress_callback: func(current, total) 2230 :param int max_connections: 2231 If set to 2 or greater, an initial get will be done for the first 2232 self.MAX_SINGLE_GET_SIZE bytes of the blob. If this is the entire blob, 2233 the method returns at this point. If it is not, it will download the 2234 remaining data parallel using the number of threads equal to 2235 max_connections. Each chunk will be of size self.MAX_CHUNK_GET_SIZE. 2236 If set to 1, a single large get request will be done. This is not 2237 generally recommended but available if very few threads should be 2238 used, network requests are very expensive, or a non-seekable stream 2239 prevents parallel download. This may also be useful if many blobs are 2240 expected to be empty as an extra request is required for empty blobs 2241 if max_connections is greater than 1. 2242 :param str lease_id: 2243 Required if the blob has an active lease. 2244 :param datetime if_modified_since: 2245 A DateTime value. Azure expects the date value passed in to be UTC. 2246 If timezone is included, any non-UTC datetimes will be converted to UTC. 2247 If a date is passed in without timezone info, it is assumed to be UTC. 2248 Specify this header to perform the operation only 2249 if the resource has been modified since the specified time. 2250 :param datetime if_unmodified_since: 2251 A DateTime value. Azure expects the date value passed in to be UTC. 2252 If timezone is included, any non-UTC datetimes will be converted to UTC. 2253 If a date is passed in without timezone info, it is assumed to be UTC. 2254 Specify this header to perform the operation only if 2255 the resource has not been modified since the specified date/time. 2256 :param str if_match: 2257 An ETag value, or the wildcard character (*). Specify this header to perform 2258 the operation only if the resource's ETag matches the value specified. 2259 :param str if_none_match: 2260 An ETag value, or the wildcard character (*). Specify this header 2261 to perform the operation only if the resource's ETag does not match 2262 the value specified. Specify the wildcard character (*) to perform 2263 the operation only if the resource does not exist, and fail the 2264 operation if it does exist. 2265 :param int timeout: 2266 The timeout parameter is expressed in seconds. This method may make 2267 multiple calls to the Azure service and the timeout will apply to 2268 each call individually. 2269 :return: A Blob with properties and metadata. If max_connections is greater 2270 than 1, the content_md5 (if set on the blob) will not be returned. If you 2271 require this value, either use get_blob_properties or set max_connections 2272 to 1. 2273 :rtype: :class:`~azure.storage.blob.models.Blob` 2274 ''' 2275 _validate_not_none('container_name', container_name) 2276 _validate_not_none('blob_name', blob_name) 2277 _validate_not_none('encoding', encoding) 2278 2279 blob = self.get_blob_to_bytes(container_name, 2280 blob_name, 2281 snapshot, 2282 start_range, 2283 end_range, 2284 validate_content, 2285 progress_callback, 2286 max_connections, 2287 lease_id, 2288 if_modified_since, 2289 if_unmodified_since, 2290 if_match, 2291 if_none_match, 2292 timeout) 2293 blob.content = blob.content.decode(encoding) 2294 return blob 2295 2296 def get_blob_metadata( 2297 self, container_name, blob_name, snapshot=None, lease_id=None, 2298 if_modified_since=None, if_unmodified_since=None, if_match=None, 2299 if_none_match=None, timeout=None): 2300 ''' 2301 Returns all user-defined metadata for the specified blob or snapshot. 2302 2303 :param str container_name: 2304 Name of existing container. 2305 :param str blob_name: 2306 Name of existing blob. 2307 :param str snapshot: 2308 The snapshot parameter is an opaque value that, 2309 when present, specifies the blob snapshot to retrieve. 2310 :param str lease_id: 2311 Required if the blob has an active lease. 2312 :param datetime if_modified_since: 2313 A DateTime value. Azure expects the date value passed in to be UTC. 2314 If timezone is included, any non-UTC datetimes will be converted to UTC. 2315 If a date is passed in without timezone info, it is assumed to be UTC. 2316 Specify this header to perform the operation only 2317 if the resource has been modified since the specified time. 2318 :param datetime if_unmodified_since: 2319 A DateTime value. Azure expects the date value passed in to be UTC. 2320 If timezone is included, any non-UTC datetimes will be converted to UTC. 2321 If a date is passed in without timezone info, it is assumed to be UTC. 2322 Specify this header to perform the operation only if 2323 the resource has not been modified since the specified date/time. 2324 :param str if_match: 2325 An ETag value, or the wildcard character (*). Specify this header to perform 2326 the operation only if the resource's ETag matches the value specified. 2327 :param str if_none_match: 2328 An ETag value, or the wildcard character (*). Specify this header 2329 to perform the operation only if the resource's ETag does not match 2330 the value specified. Specify the wildcard character (*) to perform 2331 the operation only if the resource does not exist, and fail the 2332 operation if it does exist. 2333 :param int timeout: 2334 The timeout parameter is expressed in seconds. 2335 :return: 2336 A dictionary representing the blob metadata name, value pairs. 2337 :rtype: dict(str, str) 2338 ''' 2339 _validate_not_none('container_name', container_name) 2340 _validate_not_none('blob_name', blob_name) 2341 request = HTTPRequest() 2342 request.method = 'GET' 2343 request.host_locations = self._get_host_locations(secondary=True) 2344 request.path = _get_path(container_name, blob_name) 2345 request.query = { 2346 'snapshot': _to_str(snapshot), 2347 'comp': 'metadata', 2348 'timeout': _int_to_str(timeout), 2349 } 2350 request.headers = { 2351 'x-ms-lease-id': _to_str(lease_id), 2352 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 2353 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 2354 'If-Match': _to_str(if_match), 2355 'If-None-Match': _to_str(if_none_match), 2356 } 2357 2358 return self._perform_request(request, _parse_metadata) 2359 2360 def set_blob_metadata(self, container_name, blob_name, 2361 metadata=None, lease_id=None, 2362 if_modified_since=None, if_unmodified_since=None, 2363 if_match=None, if_none_match=None, timeout=None): 2364 ''' 2365 Sets user-defined metadata for the specified blob as one or more 2366 name-value pairs. 2367 2368 :param str container_name: 2369 Name of existing container. 2370 :param str blob_name: 2371 Name of existing blob. 2372 :param metadata: 2373 Dict containing name and value pairs. Each call to this operation 2374 replaces all existing metadata attached to the blob. To remove all 2375 metadata from the blob, call this operation with no metadata headers. 2376 :type metadata: dict(str, str) 2377 :param str lease_id: 2378 Required if the blob has an active lease. 2379 :param datetime if_modified_since: 2380 A DateTime value. Azure expects the date value passed in to be UTC. 2381 If timezone is included, any non-UTC datetimes will be converted to UTC. 2382 If a date is passed in without timezone info, it is assumed to be UTC. 2383 Specify this header to perform the operation only 2384 if the resource has been modified since the specified time. 2385 :param datetime if_unmodified_since: 2386 A DateTime value. Azure expects the date value passed in to be UTC. 2387 If timezone is included, any non-UTC datetimes will be converted to UTC. 2388 If a date is passed in without timezone info, it is assumed to be UTC. 2389 Specify this header to perform the operation only if 2390 the resource has not been modified since the specified date/time. 2391 :param str if_match: 2392 An ETag value, or the wildcard character (*). Specify this header to perform 2393 the operation only if the resource's ETag matches the value specified. 2394 :param str if_none_match: 2395 An ETag value, or the wildcard character (*). Specify this header 2396 to perform the operation only if the resource's ETag does not match 2397 the value specified. Specify the wildcard character (*) to perform 2398 the operation only if the resource does not exist, and fail the 2399 operation if it does exist. 2400 :param int timeout: 2401 The timeout parameter is expressed in seconds. 2402 :return: ETag and last modified properties for the updated Blob 2403 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 2404 ''' 2405 _validate_not_none('container_name', container_name) 2406 _validate_not_none('blob_name', blob_name) 2407 request = HTTPRequest() 2408 request.method = 'PUT' 2409 request.host_locations = self._get_host_locations() 2410 request.path = _get_path(container_name, blob_name) 2411 request.query = { 2412 'comp': 'metadata', 2413 'timeout': _int_to_str(timeout), 2414 } 2415 request.headers = { 2416 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 2417 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 2418 'If-Match': _to_str(if_match), 2419 'If-None-Match': _to_str(if_none_match), 2420 'x-ms-lease-id': _to_str(lease_id), 2421 } 2422 _add_metadata_headers(metadata, request) 2423 2424 return self._perform_request(request, _parse_base_properties) 2425 2426 def _lease_blob_impl(self, container_name, blob_name, 2427 lease_action, lease_id, 2428 lease_duration, lease_break_period, 2429 proposed_lease_id, if_modified_since, 2430 if_unmodified_since, if_match, if_none_match, timeout=None): 2431 ''' 2432 Establishes and manages a lease on a blob for write and delete operations. 2433 The Lease Blob operation can be called in one of five modes: 2434 Acquire, to request a new lease. 2435 Renew, to renew an existing lease. 2436 Change, to change the ID of an existing lease. 2437 Release, to free the lease if it is no longer needed so that another 2438 client may immediately acquire a lease against the blob. 2439 Break, to end the lease but ensure that another client cannot acquire 2440 a new lease until the current lease period has expired. 2441 2442 :param str container_name: 2443 Name of existing container. 2444 :param str blob_name: 2445 Name of existing blob. 2446 :param str lease_action: 2447 Possible _LeaseActions acquire|renew|release|break|change 2448 :param str lease_id: 2449 Required if the blob has an active lease. 2450 :param int lease_duration: 2451 Specifies the duration of the lease, in seconds, or negative one 2452 (-1) for a lease that never expires. A non-infinite lease can be 2453 between 15 and 60 seconds. A lease duration cannot be changed 2454 using renew or change. 2455 :param int lease_break_period: 2456 For a break operation, this is the proposed duration of 2457 seconds that the lease should continue before it is broken, between 2458 0 and 60 seconds. This break period is only used if it is shorter 2459 than the time remaining on the lease. If longer, the time remaining 2460 on the lease is used. A new lease will not be available before the 2461 break period has expired, but the lease may be held for longer than 2462 the break period. If this header does not appear with a break 2463 operation, a fixed-duration lease breaks after the remaining lease 2464 period elapses, and an infinite lease breaks immediately. 2465 :param str proposed_lease_id: 2466 Optional for acquire, required for change. Proposed lease ID, in a 2467 GUID string format. The Blob service returns 400 (Invalid request) 2468 if the proposed lease ID is not in the correct format. 2469 :param datetime if_modified_since: 2470 A DateTime value. Azure expects the date value passed in to be UTC. 2471 If timezone is included, any non-UTC datetimes will be converted to UTC. 2472 If a date is passed in without timezone info, it is assumed to be UTC. 2473 Specify this header to perform the operation only 2474 if the resource has been modified since the specified time. 2475 :param datetime if_unmodified_since: 2476 A DateTime value. Azure expects the date value passed in to be UTC. 2477 If timezone is included, any non-UTC datetimes will be converted to UTC. 2478 If a date is passed in without timezone info, it is assumed to be UTC. 2479 Specify this header to perform the operation only if 2480 the resource has not been modified since the specified date/time. 2481 :param str if_match: 2482 An ETag value, or the wildcard character (*). Specify this header to perform 2483 the operation only if the resource's ETag matches the value specified. 2484 :param str if_none_match: 2485 An ETag value, or the wildcard character (*). Specify this header 2486 to perform the operation only if the resource's ETag does not match 2487 the value specified. Specify the wildcard character (*) to perform 2488 the operation only if the resource does not exist, and fail the 2489 operation if it does exist. 2490 :param int timeout: 2491 The timeout parameter is expressed in seconds. 2492 :return: 2493 Response headers returned from the service call. 2494 :rtype: dict(str, str) 2495 ''' 2496 _validate_not_none('container_name', container_name) 2497 _validate_not_none('blob_name', blob_name) 2498 _validate_not_none('lease_action', lease_action) 2499 request = HTTPRequest() 2500 request.method = 'PUT' 2501 request.host_locations = self._get_host_locations() 2502 request.path = _get_path(container_name, blob_name) 2503 request.query = { 2504 'comp': 'lease', 2505 'timeout': _int_to_str(timeout), 2506 } 2507 request.headers = { 2508 'x-ms-lease-id': _to_str(lease_id), 2509 'x-ms-lease-action': _to_str(lease_action), 2510 'x-ms-lease-duration': _to_str(lease_duration), 2511 'x-ms-lease-break-period': _to_str(lease_break_period), 2512 'x-ms-proposed-lease-id': _to_str(proposed_lease_id), 2513 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 2514 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 2515 'If-Match': _to_str(if_match), 2516 'If-None-Match': _to_str(if_none_match), 2517 } 2518 2519 return self._perform_request(request, _parse_lease) 2520 2521 def acquire_blob_lease(self, container_name, blob_name, 2522 lease_duration=-1, 2523 proposed_lease_id=None, 2524 if_modified_since=None, 2525 if_unmodified_since=None, 2526 if_match=None, 2527 if_none_match=None, timeout=None): 2528 ''' 2529 Requests a new lease. If the blob does not have an active lease, the Blob 2530 service creates a lease on the blob and returns a new lease ID. 2531 2532 :param str container_name: 2533 Name of existing container. 2534 :param str blob_name: 2535 Name of existing blob. 2536 :param int lease_duration: 2537 Specifies the duration of the lease, in seconds, or negative one 2538 (-1) for a lease that never expires. A non-infinite lease can be 2539 between 15 and 60 seconds. A lease duration cannot be changed 2540 using renew or change. Default is -1 (infinite lease). 2541 :param str proposed_lease_id: 2542 Proposed lease ID, in a GUID string format. The Blob service 2543 returns 400 (Invalid request) if the proposed lease ID is not 2544 in the correct format. 2545 :param datetime if_modified_since: 2546 A DateTime value. Azure expects the date value passed in to be UTC. 2547 If timezone is included, any non-UTC datetimes will be converted to UTC. 2548 If a date is passed in without timezone info, it is assumed to be UTC. 2549 Specify this header to perform the operation only 2550 if the resource has been modified since the specified time. 2551 :param datetime if_unmodified_since: 2552 A DateTime value. Azure expects the date value passed in to be UTC. 2553 If timezone is included, any non-UTC datetimes will be converted to UTC. 2554 If a date is passed in without timezone info, it is assumed to be UTC. 2555 Specify this header to perform the operation only if 2556 the resource has not been modified since the specified date/time. 2557 :param str if_match: 2558 An ETag value, or the wildcard character (*). Specify this header to perform 2559 the operation only if the resource's ETag matches the value specified. 2560 :param str if_none_match: 2561 An ETag value, or the wildcard character (*). Specify this header 2562 to perform the operation only if the resource's ETag does not match 2563 the value specified. Specify the wildcard character (*) to perform 2564 the operation only if the resource does not exist, and fail the 2565 operation if it does exist. 2566 :param int timeout: 2567 The timeout parameter is expressed in seconds. 2568 :return: the lease ID of the newly created lease. 2569 :return: str 2570 ''' 2571 _validate_not_none('lease_duration', lease_duration) 2572 2573 if lease_duration != -1 and \ 2574 (lease_duration < 15 or lease_duration > 60): 2575 raise ValueError(_ERROR_INVALID_LEASE_DURATION) 2576 lease = self._lease_blob_impl(container_name, 2577 blob_name, 2578 _LeaseActions.Acquire, 2579 None, # lease_id 2580 lease_duration, 2581 None, # lease_break_period 2582 proposed_lease_id, 2583 if_modified_since, 2584 if_unmodified_since, 2585 if_match, 2586 if_none_match, 2587 timeout) 2588 return lease['id'] 2589 2590 def renew_blob_lease(self, container_name, blob_name, 2591 lease_id, if_modified_since=None, 2592 if_unmodified_since=None, if_match=None, 2593 if_none_match=None, timeout=None): 2594 ''' 2595 Renews the lease. The lease can be renewed if the lease ID specified on 2596 the request matches that associated with the blob. Note that the lease may 2597 be renewed even if it has expired as long as the blob has not been modified 2598 or leased again since the expiration of that lease. When you renew a lease, 2599 the lease duration clock resets. 2600 2601 :param str container_name: 2602 Name of existing container. 2603 :param str blob_name: 2604 Name of existing blob. 2605 :param str lease_id: 2606 Lease ID for active lease. 2607 :param datetime if_modified_since: 2608 A DateTime value. Azure expects the date value passed in to be UTC. 2609 If timezone is included, any non-UTC datetimes will be converted to UTC. 2610 If a date is passed in without timezone info, it is assumed to be UTC. 2611 Specify this header to perform the operation only 2612 if the resource has been modified since the specified time. 2613 :param datetime if_unmodified_since: 2614 A DateTime value. Azure expects the date value passed in to be UTC. 2615 If timezone is included, any non-UTC datetimes will be converted to UTC. 2616 If a date is passed in without timezone info, it is assumed to be UTC. 2617 Specify this header to perform the operation only if 2618 the resource has not been modified since the specified date/time. 2619 :param str if_match: 2620 An ETag value, or the wildcard character (*). Specify this header to perform 2621 the operation only if the resource's ETag matches the value specified. 2622 :param str if_none_match: 2623 An ETag value, or the wildcard character (*). Specify this header 2624 to perform the operation only if the resource's ETag does not match 2625 the value specified. Specify the wildcard character (*) to perform 2626 the operation only if the resource does not exist, and fail the 2627 operation if it does exist. 2628 :param int timeout: 2629 The timeout parameter is expressed in seconds. 2630 :return: the lease ID of the renewed lease. 2631 :return: str 2632 ''' 2633 _validate_not_none('lease_id', lease_id) 2634 2635 lease = self._lease_blob_impl(container_name, 2636 blob_name, 2637 _LeaseActions.Renew, 2638 lease_id, 2639 None, # lease_duration 2640 None, # lease_break_period 2641 None, # proposed_lease_id 2642 if_modified_since, 2643 if_unmodified_since, 2644 if_match, 2645 if_none_match, 2646 timeout) 2647 return lease['id'] 2648 2649 def release_blob_lease(self, container_name, blob_name, 2650 lease_id, if_modified_since=None, 2651 if_unmodified_since=None, if_match=None, 2652 if_none_match=None, timeout=None): 2653 ''' 2654 Releases the lease. The lease may be released if the lease ID specified on the 2655 request matches that associated with the blob. Releasing the lease allows another 2656 client to immediately acquire the lease for the blob as soon as the release is complete. 2657 2658 :param str container_name: 2659 Name of existing container. 2660 :param str blob_name: 2661 Name of existing blob. 2662 :param str lease_id: 2663 Lease ID for active lease. 2664 :param datetime if_modified_since: 2665 A DateTime value. Azure expects the date value passed in to be UTC. 2666 If timezone is included, any non-UTC datetimes will be converted to UTC. 2667 If a date is passed in without timezone info, it is assumed to be UTC. 2668 Specify this header to perform the operation only 2669 if the resource has been modified since the specified time. 2670 :param datetime if_unmodified_since: 2671 A DateTime value. Azure expects the date value passed in to be UTC. 2672 If timezone is included, any non-UTC datetimes will be converted to UTC. 2673 If a date is passed in without timezone info, it is assumed to be UTC. 2674 Specify this header to perform the operation only if 2675 the resource has not been modified since the specified date/time. 2676 :param str if_match: 2677 An ETag value, or the wildcard character (*). Specify this header to perform 2678 the operation only if the resource's ETag matches the value specified. 2679 :param str if_none_match: 2680 An ETag value, or the wildcard character (*). Specify this header 2681 to perform the operation only if the resource's ETag does not match 2682 the value specified. Specify the wildcard character (*) to perform 2683 the operation only if the resource does not exist, and fail the 2684 operation if it does exist. 2685 :param int timeout: 2686 The timeout parameter is expressed in seconds. 2687 ''' 2688 _validate_not_none('lease_id', lease_id) 2689 2690 self._lease_blob_impl(container_name, 2691 blob_name, 2692 _LeaseActions.Release, 2693 lease_id, 2694 None, # lease_duration 2695 None, # lease_break_period 2696 None, # proposed_lease_id 2697 if_modified_since, 2698 if_unmodified_since, 2699 if_match, 2700 if_none_match, 2701 timeout) 2702 2703 def break_blob_lease(self, container_name, blob_name, 2704 lease_break_period=None, 2705 if_modified_since=None, 2706 if_unmodified_since=None, 2707 if_match=None, 2708 if_none_match=None, timeout=None): 2709 ''' 2710 Breaks the lease, if the blob has an active lease. Once a lease is broken, 2711 it cannot be renewed. Any authorized request can break the lease; the request 2712 is not required to specify a matching lease ID. When a lease is broken, 2713 the lease break period is allowed to elapse, during which time no lease operation 2714 except break and release can be performed on the blob. When a lease is successfully 2715 broken, the response indicates the interval in seconds until a new lease can be acquired. 2716 2717 A lease that has been broken can also be released, in which case another client may 2718 immediately acquire the lease on the blob. 2719 2720 :param str container_name: 2721 Name of existing container. 2722 :param str blob_name: 2723 Name of existing blob. 2724 :param int lease_break_period: 2725 For a break operation, this is the proposed duration of 2726 seconds that the lease should continue before it is broken, between 2727 0 and 60 seconds. This break period is only used if it is shorter 2728 than the time remaining on the lease. If longer, the time remaining 2729 on the lease is used. A new lease will not be available before the 2730 break period has expired, but the lease may be held for longer than 2731 the break period. If this header does not appear with a break 2732 operation, a fixed-duration lease breaks after the remaining lease 2733 period elapses, and an infinite lease breaks immediately. 2734 :param datetime if_modified_since: 2735 A DateTime value. Azure expects the date value passed in to be UTC. 2736 If timezone is included, any non-UTC datetimes will be converted to UTC. 2737 If a date is passed in without timezone info, it is assumed to be UTC. 2738 Specify this header to perform the operation only 2739 if the resource has been modified since the specified time. 2740 :param datetime if_unmodified_since: 2741 A DateTime value. Azure expects the date value passed in to be UTC. 2742 If timezone is included, any non-UTC datetimes will be converted to UTC. 2743 If a date is passed in without timezone info, it is assumed to be UTC. 2744 Specify this header to perform the operation only if 2745 the resource has not been modified since the specified date/time. 2746 :param str if_match: 2747 An ETag value, or the wildcard character (*). Specify this header to perform 2748 the operation only if the resource's ETag matches the value specified. 2749 :param str if_none_match: 2750 An ETag value, or the wildcard character (*). Specify this header 2751 to perform the operation only if the resource's ETag does not match 2752 the value specified. Specify the wildcard character (*) to perform 2753 the operation only if the resource does not exist, and fail the 2754 operation if it does exist. 2755 :param int timeout: 2756 The timeout parameter is expressed in seconds. 2757 :return: Approximate time remaining in the lease period, in seconds. 2758 :return: int 2759 ''' 2760 if (lease_break_period is not None) and (lease_break_period < 0 or lease_break_period > 60): 2761 raise ValueError(_ERROR_INVALID_LEASE_BREAK_PERIOD) 2762 2763 lease = self._lease_blob_impl(container_name, 2764 blob_name, 2765 _LeaseActions.Break, 2766 None, # lease_id 2767 None, # lease_duration 2768 lease_break_period, 2769 None, # proposed_lease_id 2770 if_modified_since, 2771 if_unmodified_since, 2772 if_match, 2773 if_none_match, 2774 timeout) 2775 return lease['time'] 2776 2777 def change_blob_lease(self, container_name, blob_name, 2778 lease_id, 2779 proposed_lease_id, 2780 if_modified_since=None, 2781 if_unmodified_since=None, 2782 if_match=None, 2783 if_none_match=None, timeout=None): 2784 ''' 2785 Changes the lease ID of an active lease. A change must include the current 2786 lease ID and a new lease ID. 2787 2788 :param str container_name: 2789 Name of existing container. 2790 :param str blob_name: 2791 Name of existing blob. 2792 :param str lease_id: 2793 Required if the blob has an active lease. 2794 :param str proposed_lease_id: 2795 Proposed lease ID, in a GUID string format. The Blob service returns 2796 400 (Invalid request) if the proposed lease ID is not in the correct format. 2797 :param datetime if_modified_since: 2798 A DateTime value. Azure expects the date value passed in to be UTC. 2799 If timezone is included, any non-UTC datetimes will be converted to UTC. 2800 If a date is passed in without timezone info, it is assumed to be UTC. 2801 Specify this header to perform the operation only 2802 if the resource has been modified since the specified time. 2803 :param datetime if_unmodified_since: 2804 A DateTime value. Azure expects the date value passed in to be UTC. 2805 If timezone is included, any non-UTC datetimes will be converted to UTC. 2806 If a date is passed in without timezone info, it is assumed to be UTC. 2807 Specify this header to perform the operation only if 2808 the resource has not been modified since the specified date/time. 2809 :param str if_match: 2810 An ETag value, or the wildcard character (*). Specify this header to perform 2811 the operation only if the resource's ETag matches the value specified. 2812 :param str if_none_match: 2813 An ETag value, or the wildcard character (*). Specify this header 2814 to perform the operation only if the resource's ETag does not match 2815 the value specified. Specify the wildcard character (*) to perform 2816 the operation only if the resource does not exist, and fail the 2817 operation if it does exist. 2818 :param int timeout: 2819 The timeout parameter is expressed in seconds. 2820 ''' 2821 self._lease_blob_impl(container_name, 2822 blob_name, 2823 _LeaseActions.Change, 2824 lease_id, 2825 None, # lease_duration 2826 None, # lease_break_period 2827 proposed_lease_id, 2828 if_modified_since, 2829 if_unmodified_since, 2830 if_match, 2831 if_none_match, 2832 timeout) 2833 2834 def snapshot_blob(self, container_name, blob_name, 2835 metadata=None, if_modified_since=None, 2836 if_unmodified_since=None, if_match=None, 2837 if_none_match=None, lease_id=None, timeout=None): 2838 ''' 2839 Creates a read-only snapshot of a blob. 2840 2841 :param str container_name: 2842 Name of existing container. 2843 :param str blob_name: 2844 Name of existing blob. 2845 :param metadata: 2846 Specifies a user-defined name-value pair associated with the blob. 2847 If no name-value pairs are specified, the operation will copy the 2848 base blob metadata to the snapshot. If one or more name-value pairs 2849 are specified, the snapshot is created with the specified metadata, 2850 and metadata is not copied from the base blob. 2851 :type metadata: dict(str, str) 2852 :param datetime if_modified_since: 2853 A DateTime value. Azure expects the date value passed in to be UTC. 2854 If timezone is included, any non-UTC datetimes will be converted to UTC. 2855 If a date is passed in without timezone info, it is assumed to be UTC. 2856 Specify this header to perform the operation only 2857 if the resource has been modified since the specified time. 2858 :param datetime if_unmodified_since: 2859 A DateTime value. Azure expects the date value passed in to be UTC. 2860 If timezone is included, any non-UTC datetimes will be converted to UTC. 2861 If a date is passed in without timezone info, it is assumed to be UTC. 2862 Specify this header to perform the operation only if 2863 the resource has not been modified since the specified date/time. 2864 :param str if_match: 2865 An ETag value, or the wildcard character (*). Specify this header to perform 2866 the operation only if the resource's ETag matches the value specified. 2867 :param str if_none_match: 2868 An ETag value, or the wildcard character (*). Specify this header 2869 to perform the operation only if the resource's ETag does not match 2870 the value specified. Specify the wildcard character (*) to perform 2871 the operation only if the resource does not exist, and fail the 2872 operation if it does exist. 2873 :param str lease_id: 2874 Required if the blob has an active lease. 2875 :param int timeout: 2876 The timeout parameter is expressed in seconds. 2877 :return: snapshot properties 2878 :rtype: :class:`~azure.storage.blob.models.Blob` 2879 ''' 2880 _validate_not_none('container_name', container_name) 2881 _validate_not_none('blob_name', blob_name) 2882 request = HTTPRequest() 2883 request.method = 'PUT' 2884 request.host_locations = self._get_host_locations() 2885 request.path = _get_path(container_name, blob_name) 2886 request.query = { 2887 'comp': 'snapshot', 2888 'timeout': _int_to_str(timeout), 2889 } 2890 request.headers = { 2891 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 2892 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 2893 'If-Match': _to_str(if_match), 2894 'If-None-Match': _to_str(if_none_match), 2895 'x-ms-lease-id': _to_str(lease_id) 2896 } 2897 _add_metadata_headers(metadata, request) 2898 2899 return self._perform_request(request, _parse_snapshot_blob, [blob_name]) 2900 2901 def copy_blob(self, container_name, blob_name, copy_source, 2902 metadata=None, 2903 source_if_modified_since=None, 2904 source_if_unmodified_since=None, 2905 source_if_match=None, source_if_none_match=None, 2906 destination_if_modified_since=None, 2907 destination_if_unmodified_since=None, 2908 destination_if_match=None, 2909 destination_if_none_match=None, 2910 destination_lease_id=None, 2911 source_lease_id=None, timeout=None): 2912 ''' 2913 Copies a blob asynchronously. This operation returns a copy operation 2914 properties object, including a copy ID you can use to check or abort the 2915 copy operation. The Blob service copies blobs on a best-effort basis. 2916 2917 The source blob for a copy operation may be a block blob, an append blob, 2918 or a page blob. If the destination blob already exists, it must be of the 2919 same blob type as the source blob. Any existing destination blob will be 2920 overwritten. The destination blob cannot be modified while a copy operation 2921 is in progress. 2922 2923 When copying from a page blob, the Blob service creates a destination page 2924 blob of the source blob's length, initially containing all zeroes. Then 2925 the source page ranges are enumerated, and non-empty ranges are copied. 2926 2927 For a block blob or an append blob, the Blob service creates a committed 2928 blob of zero length before returning from this operation. When copying 2929 from a block blob, all committed blocks and their block IDs are copied. 2930 Uncommitted blocks are not copied. At the end of the copy operation, the 2931 destination blob will have the same committed block count as the source. 2932 2933 When copying from an append blob, all committed blocks are copied. At the 2934 end of the copy operation, the destination blob will have the same committed 2935 block count as the source. 2936 2937 For all blob types, you can call get_blob_properties on the destination 2938 blob to check the status of the copy operation. The final blob will be 2939 committed when the copy completes. 2940 2941 :param str container_name: 2942 Name of the destination container. The container must exist. 2943 :param str blob_name: 2944 Name of the destination blob. If the destination blob exists, it will 2945 be overwritten. Otherwise, it will be created. 2946 :param str copy_source: 2947 A URL of up to 2 KB in length that specifies an Azure file or blob. 2948 The value should be URL-encoded as it would appear in a request URI. 2949 If the source is in another account, the source must either be public 2950 or must be authenticated via a shared access signature. If the source 2951 is public, no authentication is required. 2952 Examples: 2953 https://myaccount.blob.core.windows.net/mycontainer/myblob 2954 https://myaccount.blob.core.windows.net/mycontainer/myblob?snapshot=<DateTime> 2955 https://otheraccount.blob.core.windows.net/mycontainer/myblob?sastoken 2956 :param metadata: 2957 Name-value pairs associated with the blob as metadata. If no name-value 2958 pairs are specified, the operation will copy the metadata from the 2959 source blob or file to the destination blob. If one or more name-value 2960 pairs are specified, the destination blob is created with the specified 2961 metadata, and metadata is not copied from the source blob or file. 2962 :type metadata: dict(str, str) 2963 :param datetime source_if_modified_since: 2964 A DateTime value. Azure expects the date value passed in to be UTC. 2965 If timezone is included, any non-UTC datetimes will be converted to UTC. 2966 If a date is passed in without timezone info, it is assumed to be UTC. 2967 Specify this conditional header to copy the blob only if the source 2968 blob has been modified since the specified date/time. 2969 :param datetime source_if_unmodified_since: 2970 A DateTime value. Azure expects the date value passed in to be UTC. 2971 If timezone is included, any non-UTC datetimes will be converted to UTC. 2972 If a date is passed in without timezone info, it is assumed to be UTC. 2973 Specify this conditional header to copy the blob only if the source blob 2974 has not been modified since the specified date/time. 2975 :param ETag source_if_match: 2976 An ETag value, or the wildcard character (*). Specify this conditional 2977 header to copy the source blob only if its ETag matches the value 2978 specified. If the ETag values do not match, the Blob service returns 2979 status code 412 (Precondition Failed). This header cannot be specified 2980 if the source is an Azure File. 2981 :param ETag source_if_none_match: 2982 An ETag value, or the wildcard character (*). Specify this conditional 2983 header to copy the blob only if its ETag does not match the value 2984 specified. If the values are identical, the Blob service returns status 2985 code 412 (Precondition Failed). This header cannot be specified if the 2986 source is an Azure File. 2987 :param datetime destination_if_modified_since: 2988 A DateTime value. Azure expects the date value passed in to be UTC. 2989 If timezone is included, any non-UTC datetimes will be converted to UTC. 2990 If a date is passed in without timezone info, it is assumed to be UTC. 2991 Specify this conditional header to copy the blob only 2992 if the destination blob has been modified since the specified date/time. 2993 If the destination blob has not been modified, the Blob service returns 2994 status code 412 (Precondition Failed). 2995 :param datetime destination_if_unmodified_since: 2996 A DateTime value. Azure expects the date value passed in to be UTC. 2997 If timezone is included, any non-UTC datetimes will be converted to UTC. 2998 If a date is passed in without timezone info, it is assumed to be UTC. 2999 Specify this conditional header to copy the blob only 3000 if the destination blob has not been modified since the specified 3001 date/time. If the destination blob has been modified, the Blob service 3002 returns status code 412 (Precondition Failed). 3003 :param ETag destination_if_match: 3004 An ETag value, or the wildcard character (*). Specify an ETag value for 3005 this conditional header to copy the blob only if the specified ETag value 3006 matches the ETag value for an existing destination blob. If the ETag for 3007 the destination blob does not match the ETag specified for If-Match, the 3008 Blob service returns status code 412 (Precondition Failed). 3009 :param ETag destination_if_none_match: 3010 An ETag value, or the wildcard character (*). Specify an ETag value for 3011 this conditional header to copy the blob only if the specified ETag value 3012 does not match the ETag value for the destination blob. Specify the wildcard 3013 character (*) to perform the operation only if the destination blob does not 3014 exist. If the specified condition isn't met, the Blob service returns status 3015 code 412 (Precondition Failed). 3016 :param str destination_lease_id: 3017 The lease ID specified for this header must match the lease ID of the 3018 destination blob. If the request does not include the lease ID or it is not 3019 valid, the operation fails with status code 412 (Precondition Failed). 3020 :param str source_lease_id: 3021 Specify this to perform the Copy Blob operation only if 3022 the lease ID given matches the active lease ID of the source blob. 3023 :param int timeout: 3024 The timeout parameter is expressed in seconds. 3025 :return: Copy operation properties such as status, source, and ID. 3026 :rtype: :class:`~azure.storage.blob.models.CopyProperties` 3027 ''' 3028 return self._copy_blob(container_name, blob_name, copy_source, 3029 metadata, 3030 None, 3031 source_if_modified_since, source_if_unmodified_since, 3032 source_if_match, source_if_none_match, 3033 destination_if_modified_since, 3034 destination_if_unmodified_since, 3035 destination_if_match, 3036 destination_if_none_match, 3037 destination_lease_id, 3038 source_lease_id, timeout, 3039 False) 3040 3041 def _copy_blob(self, container_name, blob_name, copy_source, 3042 metadata=None, 3043 premium_page_blob_tier=None, 3044 source_if_modified_since=None, 3045 source_if_unmodified_since=None, 3046 source_if_match=None, source_if_none_match=None, 3047 destination_if_modified_since=None, 3048 destination_if_unmodified_since=None, 3049 destination_if_match=None, 3050 destination_if_none_match=None, 3051 destination_lease_id=None, 3052 source_lease_id=None, timeout=None, 3053 incremental_copy=False): 3054 ''' 3055 See copy_blob for more details. This helper method 3056 allows for standard copies as well as incremental copies which are only supported for page blobs. 3057 :param bool incremental_copy: 3058 The timeout parameter is expressed in seconds. 3059 ''' 3060 _validate_not_none('container_name', container_name) 3061 _validate_not_none('blob_name', blob_name) 3062 _validate_not_none('copy_source', copy_source) 3063 3064 if copy_source.startswith('/'): 3065 # Backwards compatibility for earlier versions of the SDK where 3066 # the copy source can be in the following formats: 3067 # - Blob in named container: 3068 # /accountName/containerName/blobName 3069 # - Snapshot in named container: 3070 # /accountName/containerName/blobName?snapshot=<DateTime> 3071 # - Blob in root container: 3072 # /accountName/blobName 3073 # - Snapshot in root container: 3074 # /accountName/blobName?snapshot=<DateTime> 3075 account, _, source = \ 3076 copy_source.partition('/')[2].partition('/') 3077 copy_source = self.protocol + '://' + \ 3078 self.primary_endpoint + '/' + source 3079 3080 request = HTTPRequest() 3081 request.method = 'PUT' 3082 request.host_locations = self._get_host_locations() 3083 request.path = _get_path(container_name, blob_name) 3084 3085 if incremental_copy: 3086 request.query = { 3087 'comp': 'incrementalcopy', 3088 'timeout': _int_to_str(timeout), 3089 } 3090 else: 3091 request.query = {'timeout': _int_to_str(timeout)} 3092 3093 request.headers = { 3094 'x-ms-copy-source': _to_str(copy_source), 3095 'x-ms-source-if-modified-since': _to_str(source_if_modified_since), 3096 'x-ms-source-if-unmodified-since': _to_str(source_if_unmodified_since), 3097 'x-ms-source-if-match': _to_str(source_if_match), 3098 'x-ms-source-if-none-match': _to_str(source_if_none_match), 3099 'If-Modified-Since': _datetime_to_utc_string(destination_if_modified_since), 3100 'If-Unmodified-Since': _datetime_to_utc_string(destination_if_unmodified_since), 3101 'If-Match': _to_str(destination_if_match), 3102 'If-None-Match': _to_str(destination_if_none_match), 3103 'x-ms-lease-id': _to_str(destination_lease_id), 3104 'x-ms-source-lease-id': _to_str(source_lease_id), 3105 'x-ms-access-tier': _to_str(premium_page_blob_tier) 3106 } 3107 _add_metadata_headers(metadata, request) 3108 3109 return self._perform_request(request, _parse_properties, [BlobProperties]).copy 3110 3111 def abort_copy_blob(self, container_name, blob_name, copy_id, 3112 lease_id=None, timeout=None): 3113 ''' 3114 Aborts a pending copy_blob operation, and leaves a destination blob 3115 with zero length and full metadata. 3116 3117 :param str container_name: 3118 Name of destination container. 3119 :param str blob_name: 3120 Name of destination blob. 3121 :param str copy_id: 3122 Copy identifier provided in the copy.id of the original 3123 copy_blob operation. 3124 :param str lease_id: 3125 Required if the destination blob has an active infinite lease. 3126 :param int timeout: 3127 The timeout parameter is expressed in seconds. 3128 ''' 3129 _validate_not_none('container_name', container_name) 3130 _validate_not_none('blob_name', blob_name) 3131 _validate_not_none('copy_id', copy_id) 3132 request = HTTPRequest() 3133 request.method = 'PUT' 3134 request.host_locations = self._get_host_locations() 3135 request.path = _get_path(container_name, blob_name) 3136 request.query = { 3137 'comp': 'copy', 3138 'copyid': _to_str(copy_id), 3139 'timeout': _int_to_str(timeout), 3140 } 3141 request.headers = { 3142 'x-ms-lease-id': _to_str(lease_id), 3143 'x-ms-copy-action': 'abort', 3144 } 3145 3146 self._perform_request(request) 3147 3148 def delete_blob(self, container_name, blob_name, snapshot=None, 3149 lease_id=None, delete_snapshots=None, 3150 if_modified_since=None, if_unmodified_since=None, 3151 if_match=None, if_none_match=None, timeout=None): 3152 ''' 3153 Marks the specified blob or snapshot for deletion. 3154 The blob is later deleted during garbage collection. 3155 3156 Note that in order to delete a blob, you must delete all of its 3157 snapshots. You can delete both at the same time with the Delete 3158 Blob operation. 3159 3160 If a delete retention policy is enabled for the service, then this operation soft deletes the blob or snapshot 3161 and retains the blob or snapshot for specified number of days. 3162 After specified number of days, blob's data is removed from the service during garbage collection. 3163 Soft deleted blob or snapshot is accessible through List Blobs API specifying include=Include.Deleted option. 3164 Soft-deleted blob or snapshot can be restored using Undelete API. 3165 3166 :param str container_name: 3167 Name of existing container. 3168 :param str blob_name: 3169 Name of existing blob. 3170 :param str snapshot: 3171 The snapshot parameter is an opaque DateTime value that, 3172 when present, specifies the blob snapshot to delete. 3173 :param str lease_id: 3174 Required if the blob has an active lease. 3175 :param ~azure.storage.blob.models.DeleteSnapshot delete_snapshots: 3176 Required if the blob has associated snapshots. 3177 :param datetime if_modified_since: 3178 A DateTime value. Azure expects the date value passed in to be UTC. 3179 If timezone is included, any non-UTC datetimes will be converted to UTC. 3180 If a date is passed in without timezone info, it is assumed to be UTC. 3181 Specify this header to perform the operation only 3182 if the resource has been modified since the specified time. 3183 :param datetime if_unmodified_since: 3184 A DateTime value. Azure expects the date value passed in to be UTC. 3185 If timezone is included, any non-UTC datetimes will be converted to UTC. 3186 If a date is passed in without timezone info, it is assumed to be UTC. 3187 Specify this header to perform the operation only if 3188 the resource has not been modified since the specified date/time. 3189 :param str if_match: 3190 An ETag value, or the wildcard character (*). Specify this header to perform 3191 the operation only if the resource's ETag matches the value specified. 3192 :param str if_none_match: 3193 An ETag value, or the wildcard character (*). Specify this header 3194 to perform the operation only if the resource's ETag does not match 3195 the value specified. Specify the wildcard character (*) to perform 3196 the operation only if the resource does not exist, and fail the 3197 operation if it does exist. 3198 :param int timeout: 3199 The timeout parameter is expressed in seconds. 3200 ''' 3201 _validate_not_none('container_name', container_name) 3202 _validate_not_none('blob_name', blob_name) 3203 request = HTTPRequest() 3204 request.method = 'DELETE' 3205 request.host_locations = self._get_host_locations() 3206 request.path = _get_path(container_name, blob_name) 3207 request.headers = { 3208 'x-ms-lease-id': _to_str(lease_id), 3209 'x-ms-delete-snapshots': _to_str(delete_snapshots), 3210 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 3211 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 3212 'If-Match': _to_str(if_match), 3213 'If-None-Match': _to_str(if_none_match), 3214 } 3215 request.query = { 3216 'snapshot': _to_str(snapshot), 3217 'timeout': _int_to_str(timeout) 3218 } 3219 3220 self._perform_request(request) 3221 3222 def undelete_blob(self, container_name, blob_name, timeout=None): 3223 ''' 3224 The undelete Blob operation restores the contents and metadata of soft deleted blob or snapshot. 3225 Attempting to undelete a blob or snapshot that is not soft deleted will succeed without any changes. 3226 3227 :param str container_name: 3228 Name of existing container. 3229 :param str blob_name: 3230 Name of existing blob. 3231 :param int timeout: 3232 The timeout parameter is expressed in seconds. 3233 ''' 3234 _validate_not_none('container_name', container_name) 3235 _validate_not_none('blob_name', blob_name) 3236 request = HTTPRequest() 3237 request.method = 'PUT' 3238 request.host_locations = self._get_host_locations() 3239 request.path = _get_path(container_name, blob_name) 3240 request.query = { 3241 'comp': 'undelete', 3242 'timeout': _int_to_str(timeout) 3243 } 3244 3245 self._perform_request(request) 3246