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 os import path 8 9from ..common._common_conversion import ( 10 _int_to_str, 11 _to_str, 12 _datetime_to_utc_string, 13 _get_content_md5, 14) 15from ..common._constants import ( 16 SERVICE_HOST_BASE, 17 DEFAULT_PROTOCOL, 18) 19from ..common._error import ( 20 _validate_not_none, 21 _validate_type_bytes, 22 _validate_encryption_required, 23 _validate_encryption_unsupported, 24 _ERROR_VALUE_NEGATIVE, 25) 26from ..common._http import HTTPRequest 27from ..common._serialization import ( 28 _get_data_bytes_only, 29 _add_metadata_headers, 30) 31from ._deserialization import ( 32 _convert_xml_to_page_ranges, 33 _parse_page_properties, 34 _parse_base_properties, 35) 36from ._encryption import _generate_blob_encryption_data 37from ._error import ( 38 _ERROR_PAGE_BLOB_SIZE_ALIGNMENT, 39) 40from ._serialization import ( 41 _get_path, 42 _validate_and_format_range_headers, 43) 44from ._upload_chunking import ( 45 _PageBlobChunkUploader, 46 _upload_blob_chunks, 47) 48from .baseblobservice import BaseBlobService 49from .models import ( 50 _BlobTypes, 51 ResourceProperties) 52 53if sys.version_info >= (3,): 54 from io import BytesIO 55else: 56 from cStringIO import StringIO as BytesIO 57 58# Keep this value sync with _ERROR_PAGE_BLOB_SIZE_ALIGNMENT 59_PAGE_ALIGNMENT = 512 60 61 62class PageBlobService(BaseBlobService): 63 ''' 64 Page blobs are a collection of 512-byte pages optimized for random read and 65 write operations. To create a page blob, you initialize the page blob and 66 specify the maximum size the page blob will grow. To add or update the 67 contents of a page blob, you write a page or pages by specifying an offset 68 and a range that align to 512-byte page boundaries. A write to a page blob 69 can overwrite just one page, some pages, or up to 4 MB of the page blob. 70 Writes to page blobs happen in-place and are immediately committed to the 71 blob. The maximum size for a page blob is 8 TB. 72 73 :ivar int MAX_PAGE_SIZE: 74 The size of the pages put by create_blob_from_* methods. Smaller pages 75 may be put if there is less data provided. The maximum page size the service 76 supports is 4MB. When using the create_blob_from_* methods, empty pages are skipped. 77 ''' 78 79 MAX_PAGE_SIZE = 4 * 1024 * 1024 80 81 def __init__(self, account_name=None, account_key=None, sas_token=None, is_emulated=False, 82 protocol=DEFAULT_PROTOCOL, endpoint_suffix=SERVICE_HOST_BASE, custom_domain=None, 83 request_session=None, connection_string=None, socket_timeout=None, token_credential=None): 84 ''' 85 :param str account_name: 86 The storage account name. This is used to authenticate requests 87 signed with an account key and to construct the storage endpoint. It 88 is required unless a connection string is given, or if a custom 89 domain is used with anonymous authentication. 90 :param str account_key: 91 The storage account key. This is used for shared key authentication. 92 If neither account key or sas token is specified, anonymous access 93 will be used. 94 :param str sas_token: 95 A shared access signature token to use to authenticate requests 96 instead of the account key. If account key and sas token are both 97 specified, account key will be used to sign. If neither are 98 specified, anonymous access will be used. 99 :param bool is_emulated: 100 Whether to use the emulator. Defaults to False. If specified, will 101 override all other parameters besides connection string and request 102 session. 103 :param str protocol: 104 The protocol to use for requests. Defaults to https. 105 :param str endpoint_suffix: 106 The host base component of the url, minus the account name. Defaults 107 to Azure (core.windows.net). Override this to use the China cloud 108 (core.chinacloudapi.cn). 109 :param str custom_domain: 110 The custom domain to use. This can be set in the Azure Portal. For 111 example, 'www.mydomain.com'. 112 :param requests.Session request_session: 113 The session object to use for http requests. 114 :param str connection_string: 115 If specified, this will override all other parameters besides 116 request session. See 117 http://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/ 118 for the connection string format. 119 :param int socket_timeout: 120 If specified, this will override the default socket timeout. The timeout specified is in seconds. 121 See DEFAULT_SOCKET_TIMEOUT in _constants.py for the default value. 122 :param token_credential: 123 A token credential used to authenticate HTTPS requests. The token value 124 should be updated before its expiration. 125 :type `~azure.storage.common.TokenCredential` 126 ''' 127 self.blob_type = _BlobTypes.PageBlob 128 super(PageBlobService, self).__init__( 129 account_name, account_key, sas_token, is_emulated, protocol, endpoint_suffix, 130 custom_domain, request_session, connection_string, socket_timeout, token_credential) 131 132 def create_blob( 133 self, container_name, blob_name, content_length, content_settings=None, 134 sequence_number=None, metadata=None, lease_id=None, if_modified_since=None, 135 if_unmodified_since=None, if_match=None, if_none_match=None, timeout=None, premium_page_blob_tier=None): 136 ''' 137 Creates a new Page Blob. 138 139 See create_blob_from_* for high level functions that handle the 140 creation and upload of large blobs with automatic chunking and 141 progress notifications. 142 143 :param str container_name: 144 Name of existing container. 145 :param str blob_name: 146 Name of blob to create or update. 147 :param int content_length: 148 Required. This header specifies the maximum size 149 for the page blob, up to 1 TB. The page blob size must be aligned 150 to a 512-byte boundary. 151 :param ~azure.storage.blob.models.ContentSettings content_settings: 152 ContentSettings object used to set properties on the blob. 153 :param int sequence_number: 154 The sequence number is a user-controlled value that you can use to 155 track requests. The value of the sequence number must be between 0 156 and 2^63 - 1.The default value is 0. 157 :param metadata: 158 Name-value pairs associated with the blob as metadata. 159 :type metadata: dict(str, str) 160 :param str lease_id: 161 Required if the blob has an active lease. 162 :param datetime if_modified_since: 163 A DateTime value. Azure expects the date value passed in to be UTC. 164 If timezone is included, any non-UTC datetimes will be converted to UTC. 165 If a date is passed in without timezone info, it is assumed to be UTC. 166 Specify this header to perform the operation only 167 if the resource has been modified since the specified time. 168 :param datetime if_unmodified_since: 169 A DateTime value. Azure expects the date value passed in to be UTC. 170 If timezone is included, any non-UTC datetimes will be converted to UTC. 171 If a date is passed in without timezone info, it is assumed to be UTC. 172 Specify this header to perform the operation only if 173 the resource has not been modified since the specified date/time. 174 :param str if_match: 175 An ETag value, or the wildcard character (*). Specify this header to perform 176 the operation only if the resource's ETag matches the value specified. 177 :param str if_none_match: 178 An ETag value, or the wildcard character (*). Specify this header 179 to perform the operation only if the resource's ETag does not match 180 the value specified. Specify the wildcard character (*) to perform 181 the operation only if the resource does not exist, and fail the 182 operation if it does exist. 183 :param int timeout: 184 The timeout parameter is expressed in seconds. 185 :param PremiumPageBlobTier premium_page_blob_tier: 186 A page blob tier value to set the blob to. The tier correlates to the size of the 187 blob and number of allowed IOPS. This is only applicable to page blobs on 188 premium storage accounts. 189 :return: ETag and last modified properties for the new Page Blob 190 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 191 ''' 192 _validate_encryption_unsupported(self.require_encryption, self.key_encryption_key) 193 194 return self._create_blob( 195 container_name, 196 blob_name, 197 content_length, 198 content_settings=content_settings, 199 sequence_number=sequence_number, 200 metadata=metadata, 201 lease_id=lease_id, 202 premium_page_blob_tier=premium_page_blob_tier, 203 if_modified_since=if_modified_since, 204 if_unmodified_since=if_unmodified_since, 205 if_match=if_match, 206 if_none_match=if_none_match, 207 timeout=timeout 208 ) 209 210 def incremental_copy_blob(self, container_name, blob_name, copy_source, 211 metadata=None, destination_if_modified_since=None, destination_if_unmodified_since=None, 212 destination_if_match=None, destination_if_none_match=None, destination_lease_id=None, 213 source_lease_id=None, timeout=None): 214 ''' 215 Copies an incremental copy of a blob asynchronously. This operation returns a copy operation 216 properties object, including a copy ID you can use to check or abort the 217 copy operation. The Blob service copies blobs on a best-effort basis. 218 219 The source blob for an incremental copy operation must be a page blob. 220 Call get_blob_properties on the destination blob to check the status of the copy operation. 221 The final blob will be committed when the copy completes. 222 223 :param str container_name: 224 Name of the destination container. The container must exist. 225 :param str blob_name: 226 Name of the destination blob. If the destination blob exists, it will 227 be overwritten. Otherwise, it will be created. 228 :param str copy_source: 229 A URL of up to 2 KB in length that specifies an Azure page blob. 230 The value should be URL-encoded as it would appear in a request URI. 231 The copy source must be a snapshot and include a valid SAS token or be public. 232 Example: 233 https://myaccount.blob.core.windows.net/mycontainer/myblob?snapshot=<DateTime>&sastoken 234 :param metadata: 235 Name-value pairs associated with the blob as metadata. If no name-value 236 pairs are specified, the operation will copy the metadata from the 237 source blob or file to the destination blob. If one or more name-value 238 pairs are specified, the destination blob is created with the specified 239 metadata, and metadata is not copied from the source blob or file. 240 :type metadata: dict(str, str). 241 :param datetime destination_if_modified_since: 242 A DateTime value. Azure expects the date value passed in to be UTC. 243 If timezone is included, any non-UTC datetimes will be converted to UTC. 244 If a date is passed in without timezone info, it is assumed to be UTC. 245 Specify this conditional header to copy the blob only 246 if the destination blob has been modified since the specified date/time. 247 If the destination blob has not been modified, the Blob service returns 248 status code 412 (Precondition Failed). 249 :param datetime destination_if_unmodified_since: 250 A DateTime value. Azure expects the date value passed in to be UTC. 251 If timezone is included, any non-UTC datetimes will be converted to UTC. 252 If a date is passed in without timezone info, it is assumed to be UTC. 253 Specify this conditional header to copy the blob only if the destination blob 254 has not been modified since the specified ate/time. If the destination blob 255 has been modified, the Blob service returns status code 412 (Precondition Failed). 256 :param ETag destination_if_match: 257 An ETag value, or the wildcard character (*). Specify an ETag value for 258 this conditional header to copy the blob only if the specified ETag value 259 matches the ETag value for an existing destination blob. If the ETag for 260 the destination blob does not match the ETag specified for If-Match, the 261 Blob service returns status code 412 (Precondition Failed). 262 :param ETag destination_if_none_match: 263 An ETag value, or the wildcard character (*). Specify an ETag value for 264 this conditional header to copy the blob only if the specified ETag value 265 does not match the ETag value for the destination blob. Specify the wildcard 266 character (*) to perform the operation only if the destination blob does not 267 exist. If the specified condition isn't met, the Blob service returns status 268 code 412 (Precondition Failed). 269 :param str destination_lease_id: 270 The lease ID specified for this header must match the lease ID of the 271 destination blob. If the request does not include the lease ID or it is not 272 valid, the operation fails with status code 412 (Precondition Failed). 273 :param str source_lease_id: 274 Specify this to perform the Copy Blob operation only if 275 the lease ID given matches the active lease ID of the source blob. 276 :param int timeout: 277 The timeout parameter is expressed in seconds. 278 :return: Copy operation properties such as status, source, and ID. 279 :rtype: :class:`~azure.storage.blob.models.CopyProperties` 280 ''' 281 return self._copy_blob(container_name, blob_name, copy_source, 282 metadata, 283 source_if_modified_since=None, source_if_unmodified_since=None, 284 source_if_match=None, source_if_none_match=None, 285 destination_if_modified_since=destination_if_modified_since, 286 destination_if_unmodified_since=destination_if_unmodified_since, 287 destination_if_match=destination_if_match, 288 destination_if_none_match=destination_if_none_match, 289 destination_lease_id=destination_lease_id, 290 source_lease_id=source_lease_id, timeout=timeout, 291 incremental_copy=True) 292 293 def update_page( 294 self, container_name, blob_name, page, start_range, end_range, 295 validate_content=False, lease_id=None, if_sequence_number_lte=None, 296 if_sequence_number_lt=None, if_sequence_number_eq=None, 297 if_modified_since=None, if_unmodified_since=None, 298 if_match=None, if_none_match=None, timeout=None): 299 ''' 300 Updates a range of pages. 301 302 :param str container_name: 303 Name of existing container. 304 :param str blob_name: 305 Name of existing blob. 306 :param bytes page: 307 Content of the page. 308 :param int start_range: 309 Start of byte range to use for writing to a section of the blob. 310 Pages must be aligned with 512-byte boundaries, the start offset 311 must be a modulus of 512 and the end offset must be a modulus of 312 512-1. Examples of valid byte ranges are 0-511, 512-1023, etc. 313 :param int end_range: 314 End of byte range to use for writing to a section of the blob. 315 Pages must be aligned with 512-byte boundaries, the start offset 316 must be a modulus of 512 and the end offset must be a modulus of 317 512-1. Examples of valid byte ranges are 0-511, 512-1023, etc. 318 :param bool validate_content: 319 If true, calculates an MD5 hash of the page content. The storage 320 service checks the hash of the content that has arrived 321 with the hash that was sent. This is primarily valuable for detecting 322 bitflips on the wire if using http instead of https as https (the default) 323 will already validate. Note that this MD5 hash is not stored with the 324 blob. 325 :param str lease_id: 326 Required if the blob has an active lease. 327 :param int if_sequence_number_lte: 328 If the blob's sequence number is less than or equal to 329 the specified value, the request proceeds; otherwise it fails. 330 :param int if_sequence_number_lt: 331 If the blob's sequence number is less than the specified 332 value, the request proceeds; otherwise it fails. 333 :param int if_sequence_number_eq: 334 If the blob's sequence number is equal to the specified 335 value, the request proceeds; otherwise it fails. 336 :param datetime if_modified_since: 337 A DateTime value. Azure expects the date value passed in to be UTC. 338 If timezone is included, any non-UTC datetimes will be converted to UTC. 339 If a date is passed in without timezone info, it is assumed to be UTC. 340 Specify this header to perform the operation only 341 if the resource has been modified since the specified time. 342 :param datetime if_unmodified_since: 343 A DateTime value. Azure expects the date value passed in to be UTC. 344 If timezone is included, any non-UTC datetimes will be converted to UTC. 345 If a date is passed in without timezone info, it is assumed to be UTC. 346 Specify this header to perform the operation only if 347 the resource has not been modified since the specified date/time. 348 :param str if_match: 349 An ETag value, or the wildcard character (*). Specify an ETag value for this conditional 350 header to write the page only if the blob's ETag value matches the 351 value specified. If the values do not match, the Blob service fails. 352 :param str if_none_match: 353 An ETag value, or the wildcard character (*). Specify an ETag value for this conditional 354 header to write the page only if the blob's ETag value does not 355 match the value specified. If the values are identical, the Blob 356 service fails. 357 :param int timeout: 358 The timeout parameter is expressed in seconds. 359 :return: ETag and last modified properties for the updated Page Blob 360 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 361 ''' 362 363 _validate_encryption_unsupported(self.require_encryption, self.key_encryption_key) 364 365 return self._update_page( 366 container_name, 367 blob_name, 368 page, 369 start_range, 370 end_range, 371 validate_content=validate_content, 372 lease_id=lease_id, 373 if_sequence_number_lte=if_sequence_number_lte, 374 if_sequence_number_lt=if_sequence_number_lt, 375 if_sequence_number_eq=if_sequence_number_eq, 376 if_modified_since=if_modified_since, 377 if_unmodified_since=if_unmodified_since, 378 if_match=if_match, 379 if_none_match=if_none_match, 380 timeout=timeout 381 ) 382 383 def update_page_from_url(self, container_name, blob_name, start_range, end_range, copy_source_url, 384 source_range_start, source_content_md5=None, source_if_modified_since=None, 385 source_if_unmodified_since=None, source_if_match=None, source_if_none_match=None, 386 lease_id=None, if_sequence_number_lte=None, if_sequence_number_lt=None, 387 if_sequence_number_eq=None, if_modified_since=None, if_unmodified_since=None, 388 if_match=None, if_none_match=None, timeout=None): 389 """ 390 Updates a range of pages to a page blob where the contents are read from a URL. 391 392 :param str container_name: 393 Name of existing container. 394 :param str blob_name: 395 Name of blob. 396 :param int start_range: 397 Start of byte range to use for writing to a section of the blob. 398 Pages must be aligned with 512-byte boundaries, the start offset 399 must be a modulus of 512 and the end offset must be a modulus of 400 512-1. Examples of valid byte ranges are 0-511, 512-1023, etc. 401 :param int end_range: 402 End of byte range to use for writing to a section of the blob. 403 Pages must be aligned with 512-byte boundaries, the start offset 404 must be a modulus of 512 and the end offset must be a modulus of 405 512-1. Examples of valid byte ranges are 0-511, 512-1023, etc. 406 :param str copy_source_url: 407 The URL of the source data. It can point to any Azure Blob or File, that is either public or has a 408 shared access signature attached. 409 :param int source_range_start: 410 This indicates the start of the range of bytes(inclusive) that has to be taken from the copy source. 411 The service will read the same number of bytes as the destination range (end_range-start_range). 412 :param str source_content_md5: 413 If given, the service will calculate the MD5 hash of the block content and compare against this value. 414 :param datetime source_if_modified_since: 415 A DateTime value. Azure expects the date value passed in to be UTC. 416 If timezone is included, any non-UTC datetimes will be converted to UTC. 417 If a date is passed in without timezone info, it is assumed to be UTC. 418 Specify this header to perform the operation only 419 if the source resource has been modified since the specified time. 420 :param datetime source_if_unmodified_since: 421 A DateTime value. Azure expects the date value passed in to be UTC. 422 If timezone is included, any non-UTC datetimes will be converted to UTC. 423 If a date is passed in without timezone info, it is assumed to be UTC. 424 Specify this header to perform the operation only if 425 the source resource has not been modified since the specified date/time. 426 :param str source_if_match: 427 An ETag value, or the wildcard character (*). Specify this header to perform 428 the operation only if the source resource's ETag matches the value specified. 429 :param str source_if_none_match: 430 An ETag value, or the wildcard character (*). Specify this header 431 to perform the operation only if the source resource's ETag does not match 432 the value specified. Specify the wildcard character (*) to perform 433 the operation only if the source resource does not exist, and fail the 434 operation if it does exist. 435 :param str lease_id: 436 Required if the blob has an active lease. 437 :param int if_sequence_number_lte: 438 If the blob's sequence number is less than or equal to 439 the specified value, the request proceeds; otherwise it fails. 440 :param int if_sequence_number_lt: 441 If the blob's sequence number is less than the specified 442 value, the request proceeds; otherwise it fails. 443 :param int if_sequence_number_eq: 444 If the blob's sequence number is equal to the specified 445 value, the request proceeds; otherwise it fails. 446 :param datetime if_modified_since: 447 A DateTime value. Azure expects the date value passed in to be UTC. 448 If timezone is included, any non-UTC datetimes will be converted to UTC. 449 If a date is passed in without timezone info, it is assumed to be UTC. 450 Specify this header to perform the operation only 451 if the resource has been modified since the specified time. 452 :param datetime if_unmodified_since: 453 A DateTime value. Azure expects the date value passed in to be UTC. 454 If timezone is included, any non-UTC datetimes will be converted to UTC. 455 If a date is passed in without timezone info, it is assumed to be UTC. 456 Specify this header to perform the operation only if 457 the resource has not been modified since the specified date/time. 458 :param str if_match: 459 An ETag value, or the wildcard character (*). Specify this header to perform 460 the operation only if the resource's ETag matches the value specified. 461 :param str if_none_match: 462 An ETag value, or the wildcard character (*). Specify this header 463 to perform the operation only if the resource's ETag does not match 464 the value specified. Specify the wildcard character (*) to perform 465 the operation only if the resource does not exist, and fail the 466 operation if it does exist. 467 :param int timeout: 468 The timeout parameter is expressed in seconds. 469 """ 470 _validate_encryption_unsupported(self.require_encryption, self.key_encryption_key) 471 _validate_not_none('container_name', container_name) 472 _validate_not_none('blob_name', blob_name) 473 _validate_not_none('copy_source_url', copy_source_url) 474 475 request = HTTPRequest() 476 request.method = 'PUT' 477 request.host_locations = self._get_host_locations() 478 request.path = _get_path(container_name, blob_name) 479 request.query = { 480 'comp': 'page', 481 'timeout': _int_to_str(timeout), 482 } 483 request.headers = { 484 'x-ms-page-write': 'update', 485 'x-ms-copy-source': copy_source_url, 486 'x-ms-source-content-md5': source_content_md5, 487 'x-ms-source-if-Modified-Since': _datetime_to_utc_string(source_if_modified_since), 488 'x-ms-source-if-Unmodified-Since': _datetime_to_utc_string(source_if_unmodified_since), 489 'x-ms-source-if-Match': _to_str(source_if_match), 490 'x-ms-source-if-None-Match': _to_str(source_if_none_match), 491 'x-ms-lease-id': _to_str(lease_id), 492 'x-ms-if-sequence-number-le': _to_str(if_sequence_number_lte), 493 'x-ms-if-sequence-number-lt': _to_str(if_sequence_number_lt), 494 'x-ms-if-sequence-number-eq': _to_str(if_sequence_number_eq), 495 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 496 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 497 'If-Match': _to_str(if_match), 498 'If-None-Match': _to_str(if_none_match) 499 } 500 _validate_and_format_range_headers( 501 request, 502 start_range, 503 end_range, 504 align_to_page=True) 505 _validate_and_format_range_headers( 506 request, 507 source_range_start, 508 source_range_start+(end_range-start_range), 509 range_header_name="x-ms-source-range") 510 511 return self._perform_request(request, _parse_page_properties) 512 513 def clear_page( 514 self, container_name, blob_name, start_range, end_range, 515 lease_id=None, if_sequence_number_lte=None, 516 if_sequence_number_lt=None, if_sequence_number_eq=None, 517 if_modified_since=None, if_unmodified_since=None, 518 if_match=None, if_none_match=None, timeout=None): 519 ''' 520 Clears a range of pages. 521 522 :param str container_name: 523 Name of existing container. 524 :param str blob_name: 525 Name of existing blob. 526 :param int start_range: 527 Start of byte range to use for writing to a section of the blob. 528 Pages must be aligned with 512-byte boundaries, the start offset 529 must be a modulus of 512 and the end offset must be a modulus of 530 512-1. Examples of valid byte ranges are 0-511, 512-1023, etc. 531 :param int end_range: 532 End of byte range to use for writing to a section of the blob. 533 Pages must be aligned with 512-byte boundaries, the start offset 534 must be a modulus of 512 and the end offset must be a modulus of 535 512-1. Examples of valid byte ranges are 0-511, 512-1023, etc. 536 :param str lease_id: 537 Required if the blob has an active lease. 538 :param int if_sequence_number_lte: 539 If the blob's sequence number is less than or equal to 540 the specified value, the request proceeds; otherwise it fails. 541 :param int if_sequence_number_lt: 542 If the blob's sequence number is less than the specified 543 value, the request proceeds; otherwise it fails. 544 :param int if_sequence_number_eq: 545 If the blob's sequence number is equal to the specified 546 value, the request proceeds; otherwise it fails. 547 :param datetime if_modified_since: 548 A DateTime value. Azure expects the date value passed in to be UTC. 549 If timezone is included, any non-UTC datetimes will be converted to UTC. 550 If a date is passed in without timezone info, it is assumed to be UTC. 551 Specify this header to perform the operation only 552 if the resource has been modified since the specified time. 553 :param datetime if_unmodified_since: 554 A DateTime value. Azure expects the date value passed in to be UTC. 555 If timezone is included, any non-UTC datetimes will be converted to UTC. 556 If a date is passed in without timezone info, it is assumed to be UTC. 557 Specify this header to perform the operation only if 558 the resource has not been modified since the specified date/time. 559 :param str if_match: 560 An ETag value, or the wildcard character (*). Specify an ETag value for this conditional 561 header to write the page only if the blob's ETag value matches the 562 value specified. If the values do not match, the Blob service fails. 563 :param str if_none_match: 564 An ETag value, or the wildcard character (*). Specify an ETag value for this conditional 565 header to write the page only if the blob's ETag value does not 566 match the value specified. If the values are identical, the Blob 567 service fails. 568 :param int timeout: 569 The timeout parameter is expressed in seconds. 570 :return: ETag and last modified properties for the updated Page Blob 571 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 572 ''' 573 _validate_not_none('container_name', container_name) 574 _validate_not_none('blob_name', blob_name) 575 576 request = HTTPRequest() 577 request.method = 'PUT' 578 request.host_locations = self._get_host_locations() 579 request.path = _get_path(container_name, blob_name) 580 request.query = { 581 'comp': 'page', 582 'timeout': _int_to_str(timeout), 583 } 584 request.headers = { 585 'x-ms-page-write': 'clear', 586 'x-ms-lease-id': _to_str(lease_id), 587 'x-ms-if-sequence-number-le': _to_str(if_sequence_number_lte), 588 'x-ms-if-sequence-number-lt': _to_str(if_sequence_number_lt), 589 'x-ms-if-sequence-number-eq': _to_str(if_sequence_number_eq), 590 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 591 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 592 'If-Match': _to_str(if_match), 593 'If-None-Match': _to_str(if_none_match) 594 } 595 _validate_and_format_range_headers( 596 request, 597 start_range, 598 end_range, 599 align_to_page=True) 600 601 return self._perform_request(request, _parse_page_properties) 602 603 def get_page_ranges( 604 self, container_name, blob_name, snapshot=None, start_range=None, 605 end_range=None, lease_id=None, if_modified_since=None, 606 if_unmodified_since=None, if_match=None, if_none_match=None, timeout=None): 607 ''' 608 Returns the list of valid page ranges for a Page Blob or snapshot 609 of a page blob. 610 611 :param str container_name: 612 Name of existing container. 613 :param str blob_name: 614 Name of existing blob. 615 :param str snapshot: 616 The snapshot parameter is an opaque DateTime value that, 617 when present, specifies the blob snapshot to retrieve information 618 from. 619 :param int start_range: 620 Start of byte range to use for getting valid page ranges. 621 If no end_range is given, all bytes after the start_range will be searched. 622 Pages must be aligned with 512-byte boundaries, the start offset 623 must be a modulus of 512 and the end offset must be a modulus of 624 512-1. Examples of valid byte ranges are 0-511, 512-, etc. 625 :param int end_range: 626 End of byte range to use for getting valid page ranges. 627 If end_range is given, start_range must be provided. 628 This range will return valid page ranges for from the offset start up to 629 offset end. 630 Pages must be aligned with 512-byte boundaries, the start offset 631 must be a modulus of 512 and the end offset must be a modulus of 632 512-1. Examples of valid byte ranges are 0-511, 512-, etc. 633 :param str lease_id: 634 Required if the blob has an active lease. 635 :param datetime if_modified_since: 636 A DateTime value. Azure expects the date value passed in to be UTC. 637 If timezone is included, any non-UTC datetimes will be converted to UTC. 638 If a date is passed in without timezone info, it is assumed to be UTC. 639 Specify this header to perform the operation only 640 if the resource has been modified since the specified time. 641 :param datetime if_unmodified_since: 642 A DateTime value. Azure expects the date value passed in to be UTC. 643 If timezone is included, any non-UTC datetimes will be converted to UTC. 644 If a date is passed in without timezone info, it is assumed to be UTC. 645 Specify this header to perform the operation only if 646 the resource has not been modified since the specified date/time. 647 :param str if_match: 648 An ETag value, or the wildcard character (*). Specify this header to perform 649 the operation only if the resource's ETag matches the value specified. 650 :param str if_none_match: 651 An ETag value, or the wildcard character (*). Specify this header 652 to perform the operation only if the resource's ETag does not match 653 the value specified. Specify the wildcard character (*) to perform 654 the operation only if the resource does not exist, and fail the 655 operation if it does exist. 656 :param int timeout: 657 The timeout parameter is expressed in seconds. 658 :return: A list of valid Page Ranges for the Page Blob. 659 :rtype: list(:class:`~azure.storage.blob.models.PageRange`) 660 ''' 661 _validate_not_none('container_name', container_name) 662 _validate_not_none('blob_name', blob_name) 663 request = HTTPRequest() 664 request.method = 'GET' 665 request.host_locations = self._get_host_locations(secondary=True) 666 request.path = _get_path(container_name, blob_name) 667 request.query = { 668 'comp': 'pagelist', 669 'snapshot': _to_str(snapshot), 670 'timeout': _int_to_str(timeout), 671 } 672 request.headers = { 673 'x-ms-lease-id': _to_str(lease_id), 674 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 675 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 676 'If-Match': _to_str(if_match), 677 'If-None-Match': _to_str(if_none_match), 678 } 679 if start_range is not None: 680 _validate_and_format_range_headers( 681 request, 682 start_range, 683 end_range, 684 start_range_required=False, 685 end_range_required=False, 686 align_to_page=True) 687 688 return self._perform_request(request, _convert_xml_to_page_ranges) 689 690 def get_page_ranges_diff( 691 self, container_name, blob_name, previous_snapshot, snapshot=None, 692 start_range=None, end_range=None, lease_id=None, if_modified_since=None, 693 if_unmodified_since=None, if_match=None, if_none_match=None, timeout=None): 694 ''' 695 The response will include only the pages that are different between either a 696 recent snapshot or the current blob and a previous snapshot, including pages 697 that were cleared. 698 699 :param str container_name: 700 Name of existing container. 701 :param str blob_name: 702 Name of existing blob. 703 :param str previous_snapshot: 704 The snapshot parameter is an opaque DateTime value that 705 specifies a previous blob snapshot to be compared 706 against a more recent snapshot or the current blob. 707 :param str snapshot: 708 The snapshot parameter is an opaque DateTime value that 709 specifies a more recent blob snapshot to be compared 710 against a previous snapshot (previous_snapshot). 711 :param int start_range: 712 Start of byte range to use for getting different page ranges. 713 If no end_range is given, all bytes after the start_range will be searched. 714 Pages must be aligned with 512-byte boundaries, the start offset 715 must be a modulus of 512 and the end offset must be a modulus of 716 512-1. Examples of valid byte ranges are 0-511, 512-, etc. 717 :param int end_range: 718 End of byte range to use for getting different page ranges. 719 If end_range is given, start_range must be provided. 720 This range will return valid page ranges for from the offset start up to 721 offset end. 722 Pages must be aligned with 512-byte boundaries, the start offset 723 must be a modulus of 512 and the end offset must be a modulus of 724 512-1. Examples of valid byte ranges are 0-511, 512-, etc. 725 :param str lease_id: 726 Required if the blob has an active lease. 727 :param datetime if_modified_since: 728 A DateTime value. Azure expects the date value passed in to be UTC. 729 If timezone is included, any non-UTC datetimes will be converted to UTC. 730 If a date is passed in without timezone info, it is assumed to be UTC. 731 Specify this header to perform the operation only 732 if the resource has been modified since the specified time. 733 :param datetime if_unmodified_since: 734 A DateTime value. Azure expects the date value passed in to be UTC. 735 If timezone is included, any non-UTC datetimes will be converted to UTC. 736 If a date is passed in without timezone info, it is assumed to be UTC. 737 Specify this header to perform the operation only if 738 the resource has not been modified since the specified date/time. 739 :param str if_match: 740 An ETag value, or the wildcard character (*). Specify this header to perform 741 the operation only if the resource's ETag matches the value specified. 742 :param str if_none_match: 743 An ETag value, or the wildcard character (*). Specify this header 744 to perform the operation only if the resource's ETag does not match 745 the value specified. Specify the wildcard character (*) to perform 746 the operation only if the resource does not exist, and fail the 747 operation if it does exist. 748 :param int timeout: 749 The timeout parameter is expressed in seconds. 750 :return: A list of different Page Ranges for the Page Blob. 751 :rtype: list(:class:`~azure.storage.blob.models.PageRange`) 752 ''' 753 _validate_not_none('container_name', container_name) 754 _validate_not_none('blob_name', blob_name) 755 _validate_not_none('previous_snapshot', previous_snapshot) 756 request = HTTPRequest() 757 request.method = 'GET' 758 request.host_locations = self._get_host_locations(secondary=True) 759 request.path = _get_path(container_name, blob_name) 760 request.query = { 761 'comp': 'pagelist', 762 'snapshot': _to_str(snapshot), 763 'prevsnapshot': _to_str(previous_snapshot), 764 'timeout': _int_to_str(timeout), 765 } 766 request.headers = { 767 'x-ms-lease-id': _to_str(lease_id), 768 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 769 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 770 'If-Match': _to_str(if_match), 771 'If-None-Match': _to_str(if_none_match), 772 } 773 if start_range is not None: 774 _validate_and_format_range_headers( 775 request, 776 start_range, 777 end_range, 778 start_range_required=False, 779 end_range_required=False, 780 align_to_page=True) 781 782 return self._perform_request(request, _convert_xml_to_page_ranges) 783 784 def set_sequence_number( 785 self, container_name, blob_name, sequence_number_action, sequence_number=None, 786 lease_id=None, if_modified_since=None, if_unmodified_since=None, 787 if_match=None, if_none_match=None, timeout=None): 788 789 ''' 790 Sets the blob sequence number. 791 792 :param str container_name: 793 Name of existing container. 794 :param str blob_name: 795 Name of existing blob. 796 :param str sequence_number_action: 797 This property indicates how the service should modify the blob's sequence 798 number. See :class:`~azure.storage.blob.models.SequenceNumberAction` for more information. 799 :param str sequence_number: 800 This property sets the blob's sequence number. The sequence number is a 801 user-controlled property that you can use to track requests and manage 802 concurrency issues. 803 :param str lease_id: 804 Required if the blob has an active lease. 805 :param datetime if_modified_since: 806 A DateTime value. Azure expects the date value passed in to be UTC. 807 If timezone is included, any non-UTC datetimes will be converted to UTC. 808 If a date is passed in without timezone info, it is assumed to be UTC. 809 Specify this header to perform the operation only 810 if the resource has been modified since the specified time. 811 :param datetime if_unmodified_since: 812 A DateTime value. Azure expects the date value passed in to be UTC. 813 If timezone is included, any non-UTC datetimes will be converted to UTC. 814 If a date is passed in without timezone info, it is assumed to be UTC. 815 Specify this header to perform the operation only if 816 the resource has not been modified since the specified date/time. 817 :param str if_match: 818 An ETag value, or the wildcard character (*). Specify this header to perform 819 the operation only if the resource's ETag matches the value specified. 820 :param str if_none_match: 821 An ETag value, or the wildcard character (*). Specify this header 822 to perform the operation only if the resource's ETag does not match 823 the value specified. Specify the wildcard character (*) to perform 824 the operation only if the resource does not exist, and fail the 825 operation if it does exist. 826 :param int timeout: 827 The timeout parameter is expressed in seconds. 828 :return: ETag and last modified properties for the updated Page Blob 829 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 830 ''' 831 _validate_not_none('container_name', container_name) 832 _validate_not_none('blob_name', blob_name) 833 _validate_not_none('sequence_number_action', sequence_number_action) 834 request = HTTPRequest() 835 request.method = 'PUT' 836 request.host_locations = self._get_host_locations() 837 request.path = _get_path(container_name, blob_name) 838 request.query = { 839 'comp': 'properties', 840 'timeout': _int_to_str(timeout), 841 } 842 request.headers = { 843 'x-ms-blob-sequence-number': _to_str(sequence_number), 844 'x-ms-sequence-number-action': _to_str(sequence_number_action), 845 'x-ms-lease-id': _to_str(lease_id), 846 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 847 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 848 'If-Match': _to_str(if_match), 849 'If-None-Match': _to_str(if_none_match), 850 } 851 852 return self._perform_request(request, _parse_page_properties) 853 854 def resize_blob( 855 self, container_name, blob_name, content_length, 856 lease_id=None, if_modified_since=None, if_unmodified_since=None, 857 if_match=None, if_none_match=None, timeout=None): 858 859 ''' 860 Resizes a page blob to the specified size. If the specified value is less 861 than the current size of the blob, then all pages above the specified value 862 are cleared. 863 864 :param str container_name: 865 Name of existing container. 866 :param str blob_name: 867 Name of existing blob. 868 :param int content_length: 869 Size to resize blob to. 870 :param str lease_id: 871 Required if the blob has an active lease. 872 :param datetime if_modified_since: 873 A DateTime value. Azure expects the date value passed in to be UTC. 874 If timezone is included, any non-UTC datetimes will be converted to UTC. 875 If a date is passed in without timezone info, it is assumed to be UTC. 876 Specify this header to perform the operation only 877 if the resource has been modified since the specified time. 878 :param datetime if_unmodified_since: 879 A DateTime value. Azure expects the date value passed in to be UTC. 880 If timezone is included, any non-UTC datetimes will be converted to UTC. 881 If a date is passed in without timezone info, it is assumed to be UTC. 882 Specify this header to perform the operation only if 883 the resource has not been modified since the specified date/time. 884 :param str if_match: 885 An ETag value, or the wildcard character (*). Specify this header to perform 886 the operation only if the resource's ETag matches the value specified. 887 :param str if_none_match: 888 An ETag value, or the wildcard character (*). Specify this header 889 to perform the operation only if the resource's ETag does not match 890 the value specified. Specify the wildcard character (*) to perform 891 the operation only if the resource does not exist, and fail the 892 operation if it does exist. 893 :param int timeout: 894 The timeout parameter is expressed in seconds. 895 :return: ETag and last modified properties for the updated Page Blob 896 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 897 ''' 898 _validate_not_none('container_name', container_name) 899 _validate_not_none('blob_name', blob_name) 900 _validate_not_none('content_length', content_length) 901 request = HTTPRequest() 902 request.method = 'PUT' 903 request.host_locations = self._get_host_locations() 904 request.path = _get_path(container_name, blob_name) 905 request.query = { 906 'comp': 'properties', 907 'timeout': _int_to_str(timeout), 908 } 909 request.headers = { 910 'x-ms-blob-content-length': _to_str(content_length), 911 'x-ms-lease-id': _to_str(lease_id), 912 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 913 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 914 'If-Match': _to_str(if_match), 915 'If-None-Match': _to_str(if_none_match), 916 } 917 918 return self._perform_request(request, _parse_page_properties) 919 920 # ----Convenience APIs----------------------------------------------------- 921 922 def create_blob_from_path( 923 self, container_name, blob_name, file_path, content_settings=None, 924 metadata=None, validate_content=False, progress_callback=None, max_connections=2, 925 lease_id=None, if_modified_since=None, if_unmodified_since=None, 926 if_match=None, if_none_match=None, timeout=None, premium_page_blob_tier=None): 927 ''' 928 Creates a new blob from a file path, or updates the content of an 929 existing blob, with automatic chunking and progress notifications. 930 Empty chunks are skipped, while non-emtpy ones(even if only partly filled) are uploaded. 931 932 :param str container_name: 933 Name of existing container. 934 :param str blob_name: 935 Name of blob to create or update. 936 :param str file_path: 937 Path of the file to upload as the blob content. 938 :param ~azure.storage.blob.models.ContentSettings content_settings: 939 ContentSettings object used to set blob properties. 940 :param metadata: 941 Name-value pairs associated with the blob as metadata. 942 :type metadata: dict(str, str) 943 :param bool validate_content: 944 If true, calculates an MD5 hash for each page of the blob. The storage 945 service checks the hash of the content that has arrived with the hash 946 that was sent. This is primarily valuable for detecting bitflips on 947 the wire if using http instead of https as https (the default) will 948 already validate. Note that this MD5 hash is not stored with the 949 blob. 950 :param progress_callback: 951 Callback for progress with signature function(current, total) where 952 current is the number of bytes transfered so far, and total is the 953 size of the blob, or None if the total size is unknown. 954 :type progress_callback: func(current, total) 955 :param int max_connections: 956 Maximum number of parallel connections to use. 957 :param str lease_id: 958 Required if the blob has an active lease. 959 :param datetime if_modified_since: 960 A DateTime value. Azure expects the date value passed in to be UTC. 961 If timezone is included, any non-UTC datetimes will be converted to UTC. 962 If a date is passed in without timezone info, it is assumed to be UTC. 963 Specify this header to perform the operation only 964 if the resource has been modified since the specified time. 965 :param datetime if_unmodified_since: 966 A DateTime value. Azure expects the date value passed in to be UTC. 967 If timezone is included, any non-UTC datetimes will be converted to UTC. 968 If a date is passed in without timezone info, it is assumed to be UTC. 969 Specify this header to perform the operation only if 970 the resource has not been modified since the specified date/time. 971 :param str if_match: 972 An ETag value, or the wildcard character (*). Specify this header to perform 973 the operation only if the resource's ETag matches the value specified. 974 :param str if_none_match: 975 An ETag value, or the wildcard character (*). Specify this header 976 to perform the operation only if the resource's ETag does not match 977 the value specified. Specify the wildcard character (*) to perform 978 the operation only if the resource does not exist, and fail the 979 operation if it does exist. 980 :param int timeout: 981 The timeout parameter is expressed in seconds. This method may make 982 multiple calls to the Azure service and the timeout will apply to 983 each call individually. 984 :param premium_page_blob_tier: 985 A page blob tier value to set the blob to. The tier correlates to the size of the 986 blob and number of allowed IOPS. This is only applicable to page blobs on 987 premium storage accounts. 988 :return: ETag and last modified properties for the Page Blob 989 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 990 ''' 991 _validate_not_none('container_name', container_name) 992 _validate_not_none('blob_name', blob_name) 993 _validate_not_none('file_path', file_path) 994 995 count = path.getsize(file_path) 996 with open(file_path, 'rb') as stream: 997 return self.create_blob_from_stream( 998 container_name=container_name, 999 blob_name=blob_name, 1000 stream=stream, 1001 count=count, 1002 content_settings=content_settings, 1003 metadata=metadata, 1004 validate_content=validate_content, 1005 progress_callback=progress_callback, 1006 max_connections=max_connections, 1007 lease_id=lease_id, 1008 if_modified_since=if_modified_since, 1009 if_unmodified_since=if_unmodified_since, 1010 if_match=if_match, 1011 if_none_match=if_none_match, 1012 timeout=timeout, 1013 premium_page_blob_tier=premium_page_blob_tier) 1014 1015 def create_blob_from_stream( 1016 self, container_name, blob_name, stream, count, content_settings=None, 1017 metadata=None, validate_content=False, progress_callback=None, 1018 max_connections=2, lease_id=None, if_modified_since=None, 1019 if_unmodified_since=None, if_match=None, if_none_match=None, timeout=None, 1020 premium_page_blob_tier=None): 1021 ''' 1022 Creates a new blob from a file/stream, or updates the content of an 1023 existing blob, with automatic chunking and progress notifications. 1024 Empty chunks are skipped, while non-emtpy ones(even if only partly filled) are uploaded. 1025 1026 :param str container_name: 1027 Name of existing container. 1028 :param str blob_name: 1029 Name of blob to create or update. 1030 :param io.IOBase stream: 1031 Opened file/stream to upload as the blob content. 1032 :param int count: 1033 Number of bytes to read from the stream. This is required, a page 1034 blob cannot be created if the count is unknown. 1035 :param ~azure.storage.blob.models.ContentSettings content_settings: 1036 ContentSettings object used to set the blob properties. 1037 :param metadata: 1038 Name-value pairs associated with the blob as metadata. 1039 :type metadata: dict(str, str) 1040 :param bool validate_content: 1041 If true, calculates an MD5 hash for each page of the blob. The storage 1042 service checks the hash of the content that has arrived with the hash 1043 that was sent. This is primarily valuable for detecting bitflips on 1044 the wire if using http instead of https as https (the default) will 1045 already validate. Note that this MD5 hash is not stored with the 1046 blob. 1047 :param progress_callback: 1048 Callback for progress with signature function(current, total) where 1049 current is the number of bytes transfered so far, and total is the 1050 size of the blob, or None if the total size is unknown. 1051 :type progress_callback: func(current, total) 1052 :param int max_connections: 1053 Maximum number of parallel connections to use. Note that parallel upload 1054 requires the stream to be seekable. 1055 :param str lease_id: 1056 Required if the blob has an active lease. 1057 :param datetime if_modified_since: 1058 A DateTime value. Azure expects the date value passed in to be UTC. 1059 If timezone is included, any non-UTC datetimes will be converted to UTC. 1060 If a date is passed in without timezone info, it is assumed to be UTC. 1061 Specify this header to perform the operation only 1062 if the resource has been modified since the specified time. 1063 :param datetime if_unmodified_since: 1064 A DateTime value. Azure expects the date value passed in to be UTC. 1065 If timezone is included, any non-UTC datetimes will be converted to UTC. 1066 If a date is passed in without timezone info, it is assumed to be UTC. 1067 Specify this header to perform the operation only if 1068 the resource has not been modified since the specified date/time. 1069 :param str if_match: 1070 An ETag value, or the wildcard character (*). Specify this header to perform 1071 the operation only if the resource's ETag matches the value specified. 1072 :param str if_none_match: 1073 An ETag value, or the wildcard character (*). Specify this header 1074 to perform the operation only if the resource's ETag does not match 1075 the value specified. Specify the wildcard character (*) to perform 1076 the operation only if the resource does not exist, and fail the 1077 operation if it does exist. 1078 :param int timeout: 1079 The timeout parameter is expressed in seconds. This method may make 1080 multiple calls to the Azure service and the timeout will apply to 1081 each call individually. 1082 :param premium_page_blob_tier: 1083 A page blob tier value to set the blob to. The tier correlates to the size of the 1084 blob and number of allowed IOPS. This is only applicable to page blobs on 1085 premium storage accounts. 1086 :return: ETag and last modified properties for the Page Blob 1087 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 1088 ''' 1089 _validate_not_none('container_name', container_name) 1090 _validate_not_none('blob_name', blob_name) 1091 _validate_not_none('stream', stream) 1092 _validate_not_none('count', count) 1093 _validate_encryption_required(self.require_encryption, self.key_encryption_key) 1094 1095 if count < 0: 1096 raise ValueError(_ERROR_VALUE_NEGATIVE.format('count')) 1097 1098 if count % _PAGE_ALIGNMENT != 0: 1099 raise ValueError(_ERROR_PAGE_BLOB_SIZE_ALIGNMENT.format(count)) 1100 1101 cek, iv, encryption_data = None, None, None 1102 if self.key_encryption_key is not None: 1103 cek, iv, encryption_data = _generate_blob_encryption_data(self.key_encryption_key) 1104 1105 response = self._create_blob( 1106 container_name=container_name, 1107 blob_name=blob_name, 1108 content_length=count, 1109 content_settings=content_settings, 1110 metadata=metadata, 1111 lease_id=lease_id, 1112 premium_page_blob_tier=premium_page_blob_tier, 1113 if_modified_since=if_modified_since, 1114 if_unmodified_since=if_unmodified_since, 1115 if_match=if_match, 1116 if_none_match=if_none_match, 1117 timeout=timeout, 1118 encryption_data=encryption_data 1119 ) 1120 1121 if count == 0: 1122 return response 1123 1124 # _upload_blob_chunks returns the block ids for block blobs so resource_properties 1125 # is passed as a parameter to get the last_modified and etag for page and append blobs. 1126 # this info is not needed for block_blobs since _put_block_list is called after which gets this info 1127 resource_properties = ResourceProperties() 1128 _upload_blob_chunks( 1129 blob_service=self, 1130 container_name=container_name, 1131 blob_name=blob_name, 1132 blob_size=count, 1133 block_size=self.MAX_PAGE_SIZE, 1134 stream=stream, 1135 max_connections=max_connections, 1136 progress_callback=progress_callback, 1137 validate_content=validate_content, 1138 lease_id=lease_id, 1139 uploader_class=_PageBlobChunkUploader, 1140 if_match=response.etag, 1141 timeout=timeout, 1142 content_encryption_key=cek, 1143 initialization_vector=iv, 1144 resource_properties=resource_properties 1145 ) 1146 1147 return resource_properties 1148 1149 def create_blob_from_bytes( 1150 self, container_name, blob_name, blob, index=0, count=None, 1151 content_settings=None, metadata=None, validate_content=False, 1152 progress_callback=None, max_connections=2, lease_id=None, 1153 if_modified_since=None, if_unmodified_since=None, if_match=None, 1154 if_none_match=None, timeout=None, premium_page_blob_tier=None): 1155 ''' 1156 Creates a new blob from an array of bytes, or updates the content 1157 of an existing blob, with automatic chunking and progress 1158 notifications. Empty chunks are skipped, while non-emtpy ones(even if only partly filled) are uploaded. 1159 1160 :param str container_name: 1161 Name of existing container. 1162 :param str blob_name: 1163 Name of blob to create or update. 1164 :param bytes blob: 1165 Content of blob as an array of bytes. 1166 :param int index: 1167 Start index in the byte array. 1168 :param int count: 1169 Number of bytes to upload. Set to None or negative value to upload 1170 all bytes starting from index. 1171 :param ~azure.storage.blob.models.ContentSettings content_settings: 1172 ContentSettings object used to set blob properties. 1173 :param metadata: 1174 Name-value pairs associated with the blob as metadata. 1175 :type metadata: dict(str, str) 1176 :param bool validate_content: 1177 If true, calculates an MD5 hash for each page of the blob. The storage 1178 service checks the hash of the content that has arrived with the hash 1179 that was sent. This is primarily valuable for detecting bitflips on 1180 the wire if using http instead of https as https (the default) will 1181 already validate. Note that this MD5 hash is not stored with the 1182 blob. 1183 :param progress_callback: 1184 Callback for progress with signature function(current, total) where 1185 current is the number of bytes transfered so far, and total is the 1186 size of the blob, or None if the total size is unknown. 1187 :type progress_callback: func(current, total) 1188 :param int max_connections: 1189 Maximum number of parallel connections to use. 1190 :param str lease_id: 1191 Required if the blob has an active lease. 1192 :param datetime if_modified_since: 1193 A DateTime value. Azure expects the date value passed in to be UTC. 1194 If timezone is included, any non-UTC datetimes will be converted to UTC. 1195 If a date is passed in without timezone info, it is assumed to be UTC. 1196 Specify this header to perform the operation only 1197 if the resource has been modified since the specified time. 1198 :param datetime if_unmodified_since: 1199 A DateTime value. Azure expects the date value passed in to be UTC. 1200 If timezone is included, any non-UTC datetimes will be converted to UTC. 1201 If a date is passed in without timezone info, it is assumed to be UTC. 1202 Specify this header to perform the operation only if 1203 the resource has not been modified since the specified date/time. 1204 :param str if_match: 1205 An ETag value, or the wildcard character (*). Specify this header to perform 1206 the operation only if the resource's ETag matches the value specified. 1207 :param str if_none_match: 1208 An ETag value, or the wildcard character (*). Specify this header 1209 to perform the operation only if the resource's ETag does not match 1210 the value specified. Specify the wildcard character (*) to perform 1211 the operation only if the resource does not exist, and fail the 1212 operation if it does exist. 1213 :param int timeout: 1214 The timeout parameter is expressed in seconds. This method may make 1215 multiple calls to the Azure service and the timeout will apply to 1216 each call individually. 1217 :param premium_page_blob_tier: 1218 A page blob tier value to set the blob to. The tier correlates to the size of the 1219 blob and number of allowed IOPS. This is only applicable to page blobs on 1220 premium storage accounts. 1221 :return: ETag and last modified properties for the Page Blob 1222 :rtype: :class:`~azure.storage.blob.models.ResourceProperties` 1223 ''' 1224 _validate_not_none('container_name', container_name) 1225 _validate_not_none('blob_name', blob_name) 1226 _validate_not_none('blob', blob) 1227 _validate_type_bytes('blob', blob) 1228 1229 if index < 0: 1230 raise IndexError(_ERROR_VALUE_NEGATIVE.format('index')) 1231 1232 if count is None or count < 0: 1233 count = len(blob) - index 1234 1235 stream = BytesIO(blob) 1236 stream.seek(index) 1237 1238 return self.create_blob_from_stream( 1239 container_name=container_name, 1240 blob_name=blob_name, 1241 stream=stream, 1242 count=count, 1243 content_settings=content_settings, 1244 metadata=metadata, 1245 validate_content=validate_content, 1246 lease_id=lease_id, 1247 progress_callback=progress_callback, 1248 max_connections=max_connections, 1249 if_modified_since=if_modified_since, 1250 if_unmodified_since=if_unmodified_since, 1251 if_match=if_match, 1252 if_none_match=if_none_match, 1253 timeout=timeout, 1254 premium_page_blob_tier=premium_page_blob_tier) 1255 1256 def set_premium_page_blob_tier( 1257 self, container_name, blob_name, premium_page_blob_tier, 1258 timeout=None): 1259 ''' 1260 Sets the page blob tiers on the blob. This API is only supported for page blobs on premium accounts. 1261 1262 :param str container_name: 1263 Name of existing container. 1264 :param str blob_name: 1265 Name of blob to update. 1266 :param PremiumPageBlobTier premium_page_blob_tier: 1267 A page blob tier value to set the blob to. The tier correlates to the size of the 1268 blob and number of allowed IOPS. This is only applicable to page blobs on 1269 premium storage accounts. 1270 :param int timeout: 1271 The timeout parameter is expressed in seconds. This method may make 1272 multiple calls to the Azure service and the timeout will apply to 1273 each call individually. 1274 ''' 1275 _validate_not_none('container_name', container_name) 1276 _validate_not_none('blob_name', blob_name) 1277 _validate_not_none('premium_page_blob_tier', premium_page_blob_tier) 1278 1279 request = HTTPRequest() 1280 request.method = 'PUT' 1281 request.host_locations = self._get_host_locations() 1282 request.path = _get_path(container_name, blob_name) 1283 request.query = { 1284 'comp': 'tier', 1285 'timeout': _int_to_str(timeout), 1286 } 1287 request.headers = { 1288 'x-ms-access-tier': _to_str(premium_page_blob_tier) 1289 } 1290 1291 self._perform_request(request) 1292 1293 def copy_blob(self, container_name, blob_name, copy_source, 1294 metadata=None, 1295 source_if_modified_since=None, 1296 source_if_unmodified_since=None, 1297 source_if_match=None, source_if_none_match=None, 1298 destination_if_modified_since=None, 1299 destination_if_unmodified_since=None, 1300 destination_if_match=None, 1301 destination_if_none_match=None, 1302 destination_lease_id=None, 1303 source_lease_id=None, timeout=None, 1304 premium_page_blob_tier=None): 1305 ''' 1306 Copies a blob asynchronously. This operation returns a copy operation 1307 properties object, including a copy ID you can use to check or abort the 1308 copy operation. The Blob service copies blobs on a best-effort basis. 1309 1310 The source blob for a copy operation must be a page blob. If the destination 1311 blob already exists, it must be of the same blob type as the source blob. 1312 Any existing destination blob will be overwritten. 1313 The destination blob cannot be modified while a copy operation is in progress. 1314 1315 When copying from a page blob, the Blob service creates a destination page 1316 blob of the source blob's length, initially containing all zeroes. Then 1317 the source page ranges are enumerated, and non-empty ranges are copied. 1318 1319 If the tier on the source blob is larger than the tier being passed to this 1320 copy operation or if the size of the blob exceeds the tier being passed to 1321 this copy operation then the operation will fail. 1322 1323 You can call get_blob_properties on the destination 1324 blob to check the status of the copy operation. The final blob will be 1325 committed when the copy completes. 1326 1327 :param str container_name: 1328 Name of the destination container. The container must exist. 1329 :param str blob_name: 1330 Name of the destination blob. If the destination blob exists, it will 1331 be overwritten. Otherwise, it will be created. 1332 :param str copy_source: 1333 A URL of up to 2 KB in length that specifies an Azure file or blob. 1334 The value should be URL-encoded as it would appear in a request URI. 1335 If the source is in another account, the source must either be public 1336 or must be authenticated via a shared access signature. If the source 1337 is public, no authentication is required. 1338 Examples: 1339 https://myaccount.blob.core.windows.net/mycontainer/myblob 1340 https://myaccount.blob.core.windows.net/mycontainer/myblob?snapshot=<DateTime> 1341 https://otheraccount.blob.core.windows.net/mycontainer/myblob?sastoken 1342 :param metadata: 1343 Name-value pairs associated with the blob as metadata. If no name-value 1344 pairs are specified, the operation will copy the metadata from the 1345 source blob or file to the destination blob. If one or more name-value 1346 pairs are specified, the destination blob is created with the specified 1347 metadata, and metadata is not copied from the source blob or file. 1348 :type metadata: dict(str, str). 1349 :param datetime source_if_modified_since: 1350 A DateTime value. Azure expects the date value passed in to be UTC. 1351 If timezone is included, any non-UTC datetimes will be converted to UTC. 1352 If a date is passed in without timezone info, it is assumed to be UTC. 1353 Specify this conditional header to copy the blob only if the source 1354 blob has been modified since the specified date/time. 1355 :param datetime source_if_unmodified_since: 1356 A DateTime value. Azure expects the date value passed in to be UTC. 1357 If timezone is included, any non-UTC datetimes will be converted to UTC. 1358 If a date is passed in without timezone info, it is assumed to be UTC. 1359 Specify this conditional header to copy the blob only if the source blob 1360 has not been modified since the specified date/time. 1361 :param ETag source_if_match: 1362 An ETag value, or the wildcard character (*). Specify this conditional 1363 header to copy the source blob only if its ETag matches the value 1364 specified. If the ETag values do not match, the Blob service returns 1365 status code 412 (Precondition Failed). This header cannot be specified 1366 if the source is an Azure File. 1367 :param ETag source_if_none_match: 1368 An ETag value, or the wildcard character (*). Specify this conditional 1369 header to copy the blob only if its ETag does not match the value 1370 specified. If the values are identical, the Blob service returns status 1371 code 412 (Precondition Failed). This header cannot be specified if the 1372 source is an Azure File. 1373 :param datetime destination_if_modified_since: 1374 A DateTime value. Azure expects the date value passed in to be UTC. 1375 If timezone is included, any non-UTC datetimes will be converted to UTC. 1376 If a date is passed in without timezone info, it is assumed to be UTC. 1377 Specify this conditional header to copy the blob only 1378 if the destination blob has been modified since the specified date/time. 1379 If the destination blob has not been modified, the Blob service returns 1380 status code 412 (Precondition Failed). 1381 :param datetime destination_if_unmodified_since: 1382 A DateTime value. Azure expects the date value passed in to be UTC. 1383 If timezone is included, any non-UTC datetimes will be converted to UTC. 1384 If a date is passed in without timezone info, it is assumed to be UTC. 1385 Specify this conditional header to copy the blob only 1386 if the destination blob has not been modified since the specified 1387 date/time. If the destination blob has been modified, the Blob service 1388 returns status code 412 (Precondition Failed). 1389 :param ETag destination_if_match: 1390 An ETag value, or the wildcard character (*). Specify an ETag value for 1391 this conditional header to copy the blob only if the specified ETag value 1392 matches the ETag value for an existing destination blob. If the ETag for 1393 the destination blob does not match the ETag specified for If-Match, the 1394 Blob service returns status code 412 (Precondition Failed). 1395 :param ETag destination_if_none_match: 1396 An ETag value, or the wildcard character (*). Specify an ETag value for 1397 this conditional header to copy the blob only if the specified ETag value 1398 does not match the ETag value for the destination blob. Specify the wildcard 1399 character (*) to perform the operation only if the destination blob does not 1400 exist. If the specified condition isn't met, the Blob service returns status 1401 code 412 (Precondition Failed). 1402 :param str destination_lease_id: 1403 The lease ID specified for this header must match the lease ID of the 1404 destination blob. If the request does not include the lease ID or it is not 1405 valid, the operation fails with status code 412 (Precondition Failed). 1406 :param str source_lease_id: 1407 Specify this to perform the Copy Blob operation only if 1408 the lease ID given matches the active lease ID of the source blob. 1409 :param int timeout: 1410 The timeout parameter is expressed in seconds. 1411 :param PageBlobTier premium_page_blob_tier: 1412 A page blob tier value to set on the destination blob. The tier correlates to 1413 the size of the blob and number of allowed IOPS. This is only applicable to 1414 page blobs on premium storage accounts. 1415 If the tier on the source blob is larger than the tier being passed to this 1416 copy operation or if the size of the blob exceeds the tier being passed to 1417 this copy operation then the operation will fail. 1418 :return: Copy operation properties such as status, source, and ID. 1419 :rtype: :class:`~azure.storage.blob.models.CopyProperties` 1420 ''' 1421 return self._copy_blob(container_name, blob_name, copy_source, 1422 metadata, premium_page_blob_tier, 1423 source_if_modified_since, source_if_unmodified_since, 1424 source_if_match, source_if_none_match, 1425 destination_if_modified_since, 1426 destination_if_unmodified_since, 1427 destination_if_match, 1428 destination_if_none_match, 1429 destination_lease_id, 1430 source_lease_id, timeout, 1431 False) 1432 1433 # -----Helper methods----------------------------------------------------- 1434 1435 def _create_blob( 1436 self, container_name, blob_name, content_length, content_settings=None, 1437 sequence_number=None, metadata=None, lease_id=None, premium_page_blob_tier=None, if_modified_since=None, 1438 if_unmodified_since=None, if_match=None, if_none_match=None, timeout=None, 1439 encryption_data=None): 1440 ''' 1441 See create_blob for more details. This helper method 1442 allows for encryption or other such special behavior because 1443 it is safely handled by the library. These behaviors are 1444 prohibited in the public version of this function. 1445 :param str encryption_data: 1446 The JSON formatted encryption metadata to upload as a part of the blob. 1447 This should only be passed internally from other methods and only applied 1448 when uploading entire blob contents immediately follows creation of the blob. 1449 ''' 1450 1451 _validate_not_none('container_name', container_name) 1452 _validate_not_none('blob_name', blob_name) 1453 _validate_not_none('content_length', content_length) 1454 request = HTTPRequest() 1455 request.method = 'PUT' 1456 request.host_locations = self._get_host_locations() 1457 request.path = _get_path(container_name, blob_name) 1458 request.query = {'timeout': _int_to_str(timeout)} 1459 request.headers = { 1460 'x-ms-blob-type': _to_str(self.blob_type), 1461 'x-ms-blob-content-length': _to_str(content_length), 1462 'x-ms-lease-id': _to_str(lease_id), 1463 'x-ms-blob-sequence-number': _to_str(sequence_number), 1464 'x-ms-access-tier': _to_str(premium_page_blob_tier), 1465 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 1466 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 1467 'If-Match': _to_str(if_match), 1468 'If-None-Match': _to_str(if_none_match) 1469 } 1470 _add_metadata_headers(metadata, request) 1471 if content_settings is not None: 1472 request.headers.update(content_settings._to_headers()) 1473 1474 if encryption_data is not None: 1475 request.headers['x-ms-meta-encryptiondata'] = encryption_data 1476 1477 return self._perform_request(request, _parse_base_properties) 1478 1479 def _update_page( 1480 self, container_name, blob_name, page, start_range, end_range, 1481 validate_content=False, lease_id=None, if_sequence_number_lte=None, 1482 if_sequence_number_lt=None, if_sequence_number_eq=None, 1483 if_modified_since=None, if_unmodified_since=None, 1484 if_match=None, if_none_match=None, timeout=None): 1485 ''' 1486 See update_page for more details. This helper method 1487 allows for encryption or other such special behavior because 1488 it is safely handled by the library. These behaviors are 1489 prohibited in the public version of this function. 1490 ''' 1491 1492 request = HTTPRequest() 1493 request.method = 'PUT' 1494 request.host_locations = self._get_host_locations() 1495 request.path = _get_path(container_name, blob_name) 1496 request.query = { 1497 'comp': 'page', 1498 'timeout': _int_to_str(timeout), 1499 } 1500 request.headers = { 1501 'x-ms-page-write': 'update', 1502 'x-ms-lease-id': _to_str(lease_id), 1503 'x-ms-if-sequence-number-le': _to_str(if_sequence_number_lte), 1504 'x-ms-if-sequence-number-lt': _to_str(if_sequence_number_lt), 1505 'x-ms-if-sequence-number-eq': _to_str(if_sequence_number_eq), 1506 'If-Modified-Since': _datetime_to_utc_string(if_modified_since), 1507 'If-Unmodified-Since': _datetime_to_utc_string(if_unmodified_since), 1508 'If-Match': _to_str(if_match), 1509 'If-None-Match': _to_str(if_none_match) 1510 } 1511 _validate_and_format_range_headers( 1512 request, 1513 start_range, 1514 end_range, 1515 align_to_page=True) 1516 request.body = _get_data_bytes_only('page', page) 1517 1518 if validate_content: 1519 computed_md5 = _get_content_md5(request.body) 1520 request.headers['Content-MD5'] = _to_str(computed_md5) 1521 1522 return self._perform_request(request, _parse_page_properties) 1523