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