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