From 14d75efef21793e95a59c8c81caf6345608a93cd Mon Sep 17 00:00:00 2001 From: antisch Date: Fri, 18 Oct 2019 13:53:27 -0700 Subject: [PATCH 1/7] Updated clients --- .../storage/blob/aio/blob_client_async.py | 343 +++++-------- .../blob/aio/blob_service_client_async.py | 14 +- .../blob/aio/container_client_async.py | 85 ++-- .../azure/storage/blob/aio/lease_async.py | 86 +--- .../azure/storage/blob/blob_client.py | 476 ++++++------------ .../azure/storage/blob/blob_service_client.py | 14 +- .../azure/storage/blob/container_client.py | 85 ++-- .../azure/storage/blob/lease.py | 90 +--- 8 files changed, 386 insertions(+), 807 deletions(-) diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_client_async.py index cdd6c80e513b..97aaef3e16f7 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_client_async.py @@ -15,9 +15,9 @@ from .._shared.base_client_async import AsyncStorageAccountHostsMixin from .._shared.policies_async import ExponentialRetry from .._shared.response_handlers import return_response_headers, process_storage_error -from .._deserialize import get_page_ranges_result +from .._deserialize import get_page_ranges_result, get_modify_conditions from .._generated.aio import AzureBlobStorage -from .._generated.models import ModifiedAccessConditions, StorageErrorException, CpkInfo +from .._generated.models import StorageErrorException, CpkInfo from .._deserialize import deserialize_blob_properties from ..blob_client import BlobClient as BlobClientBase from ._upload_helpers import ( @@ -184,15 +184,11 @@ async def upload_blob( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier: A page blob tier value to set the blob to. The tier correlates to the size of the blob and number of allowed IOPS. This is only applicable to page blobs on @@ -280,15 +276,11 @@ async def download_blob(self, offset=None, length=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -358,15 +350,11 @@ async def delete_blob(self, delete_snapshots=False, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None @@ -434,15 +422,11 @@ async def get_blob_properties(self, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -463,11 +447,7 @@ async def get_blob_properties(self, **kwargs): :caption: Getting the properties for a blob. """ access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) cpk = kwargs.pop('cpk', None) cpk_info = None if cpk: @@ -515,15 +495,11 @@ async def set_http_headers(self, content_settings=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: Blob-updated property dict (Etag and last modified) @@ -561,15 +537,11 @@ async def set_blob_metadata(self, metadata=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -629,15 +601,11 @@ async def create_page_blob( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -685,15 +653,11 @@ async def create_append_blob(self, content_settings=None, metadata=None, **kwarg If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -741,15 +705,11 @@ async def create_snapshot(self, metadata=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword lease: Required if the blob has an active lease. Value can be a LeaseClient object or the lease ID as a string. @@ -850,19 +810,12 @@ async def start_copy_from_url(self, source_url, metadata=None, incremental_copy= If a date is passed in without timezone info, it is assumed to be UTC. Specify this conditional header to copy the blob only if the source blob has not been modified since the specified date/time. - :keyword str source_if_match: - An ETag value, or the wildcard character (*). Specify this conditional - header to copy the source blob only if its ETag matches the value - specified. If the ETag values do not match, the Blob service returns - status code 412 (Precondition Failed). This header cannot be specified - if the source is an Azure File. - :keyword str source_if_none_match: - An ETag value, or the wildcard character (*). Specify this conditional - header to copy the blob only if its ETag does not match the value - specified. If the values are identical, the Blob service returns status - code 412 (Precondition Failed). This header cannot be specified if the - source is an Azure File. - :keyword ~datetime.datetime destination_if_modified_since: + :keyword str source_etag: + The source ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` source_match_condition: + The source match condition to use upon the etag. + :keyword ~datetime.datetime if_modified_since: A DateTime value. Azure expects the date value passed in to be UTC. If timezone is included, any non-UTC datetimes will be converted to UTC. If a date is passed in without timezone info, it is assumed to be UTC. @@ -870,7 +823,7 @@ async def start_copy_from_url(self, source_url, metadata=None, incremental_copy= if the destination blob has been modified since the specified date/time. If the destination blob has not been modified, the Blob service returns status code 412 (Precondition Failed). - :keyword ~datetime.datetime destination_if_unmodified_since: + :keyword ~datetime.datetime if_unmodified_since: A DateTime value. Azure expects the date value passed in to be UTC. If timezone is included, any non-UTC datetimes will be converted to UTC. If a date is passed in without timezone info, it is assumed to be UTC. @@ -878,19 +831,11 @@ async def start_copy_from_url(self, source_url, metadata=None, incremental_copy= if the destination blob has not been modified since the specified date/time. If the destination blob has been modified, the Blob service returns status code 412 (Precondition Failed). - :keyword str destination_if_match: - An ETag value, or the wildcard character (*). Specify an ETag value for - this conditional header to copy the blob only if the specified ETag value - matches the ETag value for an existing destination blob. If the ETag for - the destination blob does not match the ETag specified for If-Match, the - Blob service returns status code 412 (Precondition Failed). - :keyword str destination_if_none_match: - An ETag value, or the wildcard character (*). Specify an ETag value for - this conditional header to copy the blob only if the specified ETag value - does not match the ETag value for the destination blob. Specify the wildcard - character (*) to perform the operation only if the destination blob does not - exist. If the specified condition isn't met, the Blob service returns status - code 412 (Precondition Failed). + :keyword str etag: + The destination ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The destination match condition to use upon the etag. :keyword destination_lease: The lease ID specified for this header must match the lease ID of the destination blob. If the request does not include the lease ID or it is not @@ -995,15 +940,11 @@ async def acquire_lease(self, lease_duration=-1, lease_id=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: A LeaseClient object. @@ -1232,15 +1173,11 @@ async def commit_block_list( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.StandardBlobTier standard_blob_tier: A standard blob tier value to set the blob to. For this version of the library, this is only applicable to block blobs on standard storage accounts. @@ -1335,15 +1272,11 @@ async def get_page_ranges( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :keyword lease: @@ -1401,15 +1334,11 @@ async def set_sequence_number( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: Blob-updated property dict (Etag and last modified). @@ -1448,15 +1377,11 @@ async def resize_blob(self, size, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier: A page blob tier value to set the blob to. The tier correlates to the size of the blob and number of allowed IOPS. This is only applicable to page blobs on @@ -1527,15 +1452,11 @@ async def upload_page( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify an ETag value for this conditional - header to write the page only if the blob's ETag value matches the - value specified. If the values do not match, the Blob service fails. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify an ETag value for this conditional - header to write the page only if the blob's ETag value does not - match the value specified. If the values are identical, the Blob - service fails. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -1597,15 +1518,11 @@ async def upload_pages_from_url(self, source_url, # type: str If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the source resource has not been modified since the specified date/time. - :keyword str source_if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the source resource's ETag matches the value specified. - :keyword str source_if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the source resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the source resource does not exist, and fail the - operation if it does exist. + :keyword str source_etag: + The source ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` source_match_condition: + The source match condition to use upon the etag. :keyword str lease: Required if the blob has an active lease. :keyword int if_sequence_number_lte: @@ -1629,15 +1546,11 @@ async def upload_pages_from_url(self, source_url, # type: str If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + The destination ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The destination match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -1699,15 +1612,11 @@ async def clear_page(self, offset, length, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify an ETag value for this conditional - header to write the page only if the blob's ETag value matches the - value specified. If the values do not match, the Blob service fails. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify an ETag value for this conditional - header to write the page only if the blob's ETag value does not - match the value specified. If the values are identical, the Blob - service fails. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier: A page blob tier value to set the blob to. The tier correlates to the size of the blob and number of allowed IOPS. This is only applicable to page blobs on @@ -1771,15 +1680,11 @@ async def append_block( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword str encoding: Defaults to UTF-8. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: @@ -1848,15 +1753,11 @@ async def append_block_from_url(self, copy_source_url, # type: str If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + The destination ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The destination match condition to use upon the etag. :keyword ~datetime.datetime source_if_modified_since: A DateTime value. Azure expects the date value passed in to be UTC. If timezone is included, any non-UTC datetimes will be converted to UTC. @@ -1869,15 +1770,11 @@ async def append_block_from_url(self, copy_source_url, # type: str If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the source resource has not been modified since the specified date/time. - :keyword str source_if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the source resource's ETag matches the value specified. - :keyword str source_if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the source resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the source resource does not exist, and fail the - operation if it does exist. + :keyword str source_etag: + The source ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` source_match_condition: + The source match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_service_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_service_client_async.py index cca75e3c69c0..d7d8607740f2 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_service_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_service_client_async.py @@ -432,15 +432,11 @@ async def delete_container( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/container_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/container_client_async.py index 684034ed93ff..c0288e68cdd8 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/container_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/container_client_async.py @@ -25,10 +25,9 @@ return_headers_and_deserialized) from .._generated.aio import AzureBlobStorage from .._generated.models import ( - ModifiedAccessConditions, StorageErrorException, SignedIdentifier) -from .._deserialize import deserialize_container_properties +from .._deserialize import deserialize_container_properties, get_modify_conditions from ..container_client import ContainerClient as ContainerClientBase from ..lease import get_access_conditions from ..models import ContainerProperties, BlobProperties, BlobType # pylint: disable=unused-import @@ -180,15 +179,11 @@ async def delete_container( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None @@ -204,11 +199,7 @@ async def delete_container( """ lease = kwargs.pop('lease', None) access_conditions = get_access_conditions(lease) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) timeout = kwargs.pop('timeout', None) try: await self._client.container.delete( @@ -250,15 +241,11 @@ async def acquire_lease( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: A LeaseClient object, that can be run in a context manager. @@ -373,7 +360,7 @@ async def set_container_metadata( # type: ignore headers.update(add_metadata_headers(metadata)) lease = kwargs.pop('lease', None) access_conditions = get_access_conditions(lease) - mod_conditions = ModifiedAccessConditions(if_modified_since=kwargs.pop('if_modified_since', None)) + mod_conditions = get_modify_conditions(kwargs) timeout = kwargs.pop('timeout', None) try: return await self._client.container.set_metadata( # type: ignore @@ -485,9 +472,7 @@ async def set_container_access_policy( identifiers.append(SignedIdentifier(id=key, access_policy=value)) # type: ignore signed_identifiers = identifiers # type: ignore - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None)) + mod_conditions = get_modify_conditions(kwargs) access_conditions = get_access_conditions(lease) try: return await self._client.container.set_access_policy( @@ -647,15 +632,11 @@ async def upload_blob( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. This method may make multiple calls to the Azure service and the timeout will apply to @@ -753,15 +734,11 @@ async def delete_blob( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None @@ -821,15 +798,11 @@ async def delete_blobs( # pylint: disable=arguments-differ If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :return: An async iterator of responses, one for each blob in order diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/lease_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/lease_async.py index bfca10c9ec33..a44b3e2f146e 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/lease_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/lease_async.py @@ -14,8 +14,8 @@ from .._shared.response_handlers import return_response_headers, process_storage_error from .._generated.models import ( StorageErrorException, - ModifiedAccessConditions, LeaseAccessConditions) +from .._deserialize import get_modify_conditions from ..lease import LeaseClient as LeaseClientBase if TYPE_CHECKING: @@ -86,24 +86,16 @@ async def acquire(self, lease_duration=-1, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = await self._client.acquire_lease( timeout=kwargs.pop('timeout', None), @@ -141,24 +133,16 @@ async def renew(self, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :return: None """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = await self._client.renew_lease( lease_id=self.id, @@ -193,24 +177,16 @@ async def release(self, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :return: None """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = await self._client.release_lease( lease_id=self.id, @@ -244,24 +220,16 @@ async def change(self, proposed_lease_id, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :return: None """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = await self._client.change_lease( lease_id=self.id, @@ -315,9 +283,7 @@ async def break_lease(self, lease_break_period=None, **kwargs): :return: Approximate time remaining in the lease period, in seconds. :rtype: int """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = await self._client.break_lease( timeout=kwargs.pop('timeout', None), diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/blob_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/blob_client.py index 958eeb28bdec..8aeb0c7c43f1 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/blob_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/blob_client.py @@ -27,21 +27,23 @@ add_metadata_headers, get_length, read_length, validate_and_format_range_headers) from ._shared.response_handlers import return_response_headers, process_storage_error -from ._deserialize import get_page_ranges_result from ._generated import AzureBlobStorage from ._generated.models import ( # pylint: disable=unused-import DeleteSnapshotsOptionType, BlobHTTPHeaders, BlockLookupList, AppendPositionAccessConditions, - SourceModifiedAccessConditions, - ModifiedAccessConditions, SequenceNumberAccessConditions, StorageErrorException, UserDelegationKey, CpkInfo) -from ._deserialize import deserialize_blob_properties, deserialize_blob_stream +from ._deserialize import ( + get_page_ranges_result, + get_modify_conditions, + get_source_conditions, + deserialize_blob_properties, + deserialize_blob_stream) from ._upload_helpers import ( upload_block_blob, upload_append_blob, @@ -443,11 +445,7 @@ def _upload_blob_options( # pylint:disable=too-many-statements headers = kwargs.pop('headers', {}) headers.update(add_metadata_headers(metadata)) kwargs['lease_access_conditions'] = get_access_conditions(kwargs.pop('lease', None)) - kwargs['modified_access_conditions'] = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + kwargs['modified_access_conditions'] = get_modify_conditions(kwargs) if content_settings: kwargs['blob_headers'] = BlobHTTPHeaders( blob_cache_control=content_settings.cache_control, @@ -531,15 +529,11 @@ def upload_blob( # pylint: disable=too-many-locals If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier: A page blob tier value to set the blob to. The tier correlates to the size of the blob and number of allowed IOPS. This is only applicable to page blobs on @@ -602,11 +596,7 @@ def _download_blob_options(self, offset=None, length=None, **kwargs): validate_content = kwargs.pop('validate_content', False) access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) cpk = kwargs.pop('cpk', None) cpk_info = None @@ -670,15 +660,11 @@ def download_blob(self, offset=None, length=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -714,11 +700,7 @@ def download_blob(self, offset=None, length=None, **kwargs): def _generic_delete_blob_options(delete_snapshots=False, **kwargs): # type: (bool, **Any) -> Dict[str, Any] access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) if delete_snapshots: delete_snapshots = DeleteSnapshotsOptionType(delete_snapshots) options = { @@ -773,15 +755,11 @@ def delete_blob(self, delete_snapshots=False, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None @@ -849,15 +827,11 @@ def get_blob_properties(self, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -878,11 +852,7 @@ def get_blob_properties(self, **kwargs): """ # TODO: extract this out as _get_blob_properties_options access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) cpk = kwargs.pop('cpk', None) cpk_info = None if cpk: @@ -908,11 +878,7 @@ def get_blob_properties(self, **kwargs): def _set_http_headers_options(self, content_settings=None, **kwargs): # type: (Optional[ContentSettings], **Any) -> Dict[str, Any] access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) blob_headers = None if content_settings: blob_headers = BlobHTTPHeaders( @@ -957,15 +923,11 @@ def set_http_headers(self, content_settings=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: Blob-updated property dict (Etag and last modified) @@ -982,11 +944,7 @@ def _set_blob_metadata_options(self, metadata=None, **kwargs): headers = kwargs.pop('headers', {}) headers.update(add_metadata_headers(metadata)) access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) cpk = kwargs.pop('cpk', None) cpk_info = None @@ -1031,15 +989,11 @@ def set_blob_metadata(self, metadata=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -1068,11 +1022,7 @@ def _create_page_blob_options( # type: ignore headers = kwargs.pop('headers', {}) headers.update(add_metadata_headers(metadata)) access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) blob_headers = None if content_settings: blob_headers = BlobHTTPHeaders( @@ -1156,15 +1106,11 @@ def create_page_blob( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -1193,11 +1139,7 @@ def _create_append_blob_options(self, content_settings=None, metadata=None, **kw headers = kwargs.pop('headers', {}) headers.update(add_metadata_headers(metadata)) access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) blob_headers = None if content_settings: blob_headers = BlobHTTPHeaders( @@ -1255,15 +1197,11 @@ def create_append_blob(self, content_settings=None, metadata=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -1288,11 +1226,7 @@ def _create_snapshot_options(self, metadata=None, **kwargs): headers = kwargs.pop('headers', {}) headers.update(add_metadata_headers(metadata)) access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) cpk = kwargs.pop('cpk', None) cpk_info = None @@ -1340,15 +1274,11 @@ def create_snapshot(self, metadata=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword lease: Required if the blob has an active lease. Value can be a LeaseClient object or the lease ID as a string. @@ -1395,11 +1325,7 @@ def _start_copy_from_url_options(self, source_url, metadata=None, incremental_co headers['x-ms-requires-sync'] = str(kwargs.pop('requires_sync')) timeout = kwargs.pop('timeout', None) - dest_mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('destination_if_modified_since', None), - if_unmodified_since=kwargs.pop('destination_if_unmodified_since', None), - if_match=kwargs.pop('destination_if_match', None), - if_none_match=kwargs.pop('destination_if_none_match', None)) + dest_mod_conditions = get_modify_conditions(kwargs) options = { 'copy_source': source_url, 'timeout': timeout, @@ -1408,11 +1334,7 @@ def _start_copy_from_url_options(self, source_url, metadata=None, incremental_co 'cls': return_response_headers, } if not incremental_copy: - source_mod_conditions = SourceModifiedAccessConditions( - source_if_modified_since=kwargs.pop('source_if_modified_since', None), - source_if_unmodified_since=kwargs.pop('source_if_unmodified_since', None), - source_if_match=kwargs.pop('source_if_match', None), - source_if_none_match=kwargs.pop('source_if_none_match', None)) + source_mod_conditions = get_source_conditions(kwargs) dest_access_conditions = get_access_conditions(kwargs.pop('destination_lease', None)) options['source_modified_access_conditions'] = source_mod_conditions options['lease_access_conditions'] = dest_access_conditions @@ -1491,19 +1413,12 @@ def start_copy_from_url(self, source_url, metadata=None, incremental_copy=False, If a date is passed in without timezone info, it is assumed to be UTC. Specify this conditional header to copy the blob only if the source blob has not been modified since the specified date/time. - :keyword str source_if_match: - An ETag value, or the wildcard character (*). Specify this conditional - header to copy the source blob only if its ETag matches the value - specified. If the ETag values do not match, the Blob service returns - status code 412 (Precondition Failed). This header cannot be specified - if the source is an Azure File. - :keyword str source_if_none_match: - An ETag value, or the wildcard character (*). Specify this conditional - header to copy the blob only if its ETag does not match the value - specified. If the values are identical, the Blob service returns status - code 412 (Precondition Failed). This header cannot be specified if the - source is an Azure File. - :keyword ~datetime.datetime destination_if_modified_since: + :keyword str source_etag: + The source ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` source_match_condition: + The source match condition to use upon the etag. + :keyword ~datetime.datetime if_modified_since: A DateTime value. Azure expects the date value passed in to be UTC. If timezone is included, any non-UTC datetimes will be converted to UTC. If a date is passed in without timezone info, it is assumed to be UTC. @@ -1511,7 +1426,7 @@ def start_copy_from_url(self, source_url, metadata=None, incremental_copy=False, if the destination blob has been modified since the specified date/time. If the destination blob has not been modified, the Blob service returns status code 412 (Precondition Failed). - :keyword ~datetime.datetime destination_if_unmodified_since: + :keyword ~datetime.datetime if_unmodified_since: A DateTime value. Azure expects the date value passed in to be UTC. If timezone is included, any non-UTC datetimes will be converted to UTC. If a date is passed in without timezone info, it is assumed to be UTC. @@ -1519,19 +1434,11 @@ def start_copy_from_url(self, source_url, metadata=None, incremental_copy=False, if the destination blob has not been modified since the specified date/time. If the destination blob has been modified, the Blob service returns status code 412 (Precondition Failed). - :keyword str destination_if_match: - An ETag value, or the wildcard character (*). Specify an ETag value for - this conditional header to copy the blob only if the specified ETag value - matches the ETag value for an existing destination blob. If the ETag for - the destination blob does not match the ETag specified for If-Match, the - Blob service returns status code 412 (Precondition Failed). - :keyword str destination_if_none_match: - An ETag value, or the wildcard character (*). Specify an ETag value for - this conditional header to copy the blob only if the specified ETag value - does not match the ETag value for the destination blob. Specify the wildcard - character (*) to perform the operation only if the destination blob does not - exist. If the specified condition isn't met, the Blob service returns status - code 412 (Precondition Failed). + :keyword str etag: + The destination ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The destination match condition to use upon the etag. :keyword destination_lease: The lease ID specified for this header must match the lease ID of the destination blob. If the request does not include the lease ID or it is not @@ -1653,15 +1560,11 @@ def acquire_lease(self, lease_duration=-1, lease_id=None, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: A LeaseClient object. @@ -1965,11 +1868,7 @@ def _commit_block_list_options( # type: ignore headers.update(add_metadata_headers(metadata)) blob_headers = None access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) if content_settings: blob_headers = BlobHTTPHeaders( blob_cache_control=content_settings.cache_control, @@ -2046,15 +1945,11 @@ def commit_block_list( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :param ~azure.storage.blob.StandardBlobTier standard_blob_tier: A standard blob tier value to set the blob to. For this version of the library, this is only applicable to block blobs on standard storage accounts. @@ -2118,11 +2013,7 @@ def _get_page_ranges_options( # type: ignore ): # type: (...) -> Dict[str, Any] access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) if length is not None: length = offset + length - 1 # Reformat to an inclusive range index page_range, _ = validate_and_format_range_headers( @@ -2190,15 +2081,11 @@ def get_page_ranges( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: @@ -2223,11 +2110,7 @@ def get_page_ranges( # type: ignore def _set_sequence_number_options(self, sequence_number_action, sequence_number=None, **kwargs): # type: (Union[str, SequenceNumberAction], Optional[str], **Any) -> Dict[str, Any] access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) if sequence_number_action is None: raise ValueError("A sequence number action must be specified") options = { @@ -2268,15 +2151,11 @@ def set_sequence_number(self, sequence_number_action, sequence_number=None, **kw If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: Blob-updated property dict (Etag and last modified). @@ -2292,11 +2171,7 @@ def set_sequence_number(self, sequence_number_action, sequence_number=None, **kw def _resize_blob_options(self, size, **kwargs): # type: (int, **Any) -> Dict[str, Any] access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) if size is None: raise ValueError("A content length must be specified for a Page Blob.") @@ -2343,15 +2218,11 @@ def resize_blob(self, size, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.PremiumPageBlobTier premium_page_blob_tier: A page blob tier value to set the blob to. The tier correlates to the size of the blob and number of allowed IOPS. This is only applicable to page blobs on @@ -2391,11 +2262,7 @@ def _upload_page_options( # type: ignore if_sequence_number_less_than=kwargs.pop('if_sequence_number_lt', None), if_sequence_number_equal_to=kwargs.pop('if_sequence_number_eq', None) ) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) validate_content = kwargs.pop('validate_content', False) cpk = kwargs.pop('cpk', None) @@ -2474,15 +2341,11 @@ def upload_page( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify an ETag value for this conditional - header to write the page only if the blob's ETag value matches the - value specified. If the values do not match, the Blob service fails. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify an ETag value for this conditional - header to write the page only if the blob's ETag value does not - match the value specified. If the values are identical, the Blob - service fails. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :param ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -2535,16 +2398,8 @@ def _upload_pages_from_url_options( # type: ignore if_sequence_number_equal_to=kwargs.pop('if_sequence_number_eq', None) ) access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) - source_mod_conditions = SourceModifiedAccessConditions( - source_if_modified_since=kwargs.pop('source_if_modified_since', None), - source_if_unmodified_since=kwargs.pop('source_if_unmodified_since', None), - source_if_match=kwargs.pop('source_if_match', None), - source_if_none_match=kwargs.pop('source_if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) + source_mod_conditions = get_source_conditions(kwargs) source_content_md5 = kwargs.pop('source_content_md5', None) cpk = kwargs.pop('cpk', None) @@ -2612,15 +2467,11 @@ def upload_pages_from_url(self, source_url, # type: str If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the source resource has not been modified since the specified date/time. - :keyword str source_if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the source resource's ETag matches the value specified. - :keyword str source_if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the source resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the source resource does not exist, and fail the - operation if it does exist. + :keyword str source_etag: + The source ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` source_match_condition: + The source match condition to use upon the etag. :param str lease: Required if the blob has an active lease. :keyword int if_sequence_number_lte: @@ -2644,15 +2495,11 @@ def upload_pages_from_url(self, source_url, # type: str If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + The destination ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The destination match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -2684,12 +2531,7 @@ def _clear_page_options(self, offset, length, **kwargs): if_sequence_number_less_than=kwargs.pop('if_sequence_number_lt', None), if_sequence_number_equal_to=kwargs.pop('if_sequence_number_eq', None) ) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None) - ) + mod_conditions = get_modify_conditions(kwargs) if offset is None or offset % 512 != 0: raise ValueError("offset must be an integer that aligns with 512 page size") if length is None or length % 512 != 0: @@ -2757,15 +2599,11 @@ def clear_page(self, offset, length, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify an ETag value for this conditional - header to write the page only if the blob's ETag value matches the - value specified. If the values do not match, the Blob service fails. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify an ETag value for this conditional - header to write the page only if the blob's ETag value does not - match the value specified. If the values are identical, the Blob - service fails. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. @@ -2812,11 +2650,7 @@ def _append_block_options( # type: ignore append_position=appendpos_condition ) access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) cpk = kwargs.pop('cpk', None) cpk_info = None @@ -2887,15 +2721,11 @@ def append_block( # type: ignore If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword str encoding: Defaults to UTF-8. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: @@ -2949,16 +2779,8 @@ def _append_block_from_url_options( # type: ignore append_position=appendpos_condition ) access_conditions = get_access_conditions(kwargs.pop('lease', None)) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) - source_mod_conditions = SourceModifiedAccessConditions( - source_if_modified_since=kwargs.pop('source_if_modified_since', None), - source_if_unmodified_since=kwargs.pop('source_if_unmodified_since', None), - source_if_match=kwargs.pop('source_if_match', None), - source_if_none_match=kwargs.pop('source_if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) + source_mod_conditions = get_source_conditions(kwargs) cpk = kwargs.pop('cpk', None) cpk_info = None @@ -3030,15 +2852,11 @@ def append_block_from_url(self, copy_source_url, # type: str If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + The destination ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The destination match condition to use upon the etag. :keyword ~datetime.datetime source_if_modified_since: A DateTime value. Azure expects the date value passed in to be UTC. If timezone is included, any non-UTC datetimes will be converted to UTC. @@ -3051,15 +2869,11 @@ def append_block_from_url(self, copy_source_url, # type: str If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the source resource has not been modified since the specified date/time. - :keyword str source_if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the source resource's ETag matches the value specified. - :keyword str source_if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the source resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the source resource does not exist, and fail the - operation if it does exist. + :keyword str source_etag: + The source ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` source_match_condition: + The source match condition to use upon the etag. :keyword ~azure.storage.blob.CustomerProvidedEncryptionKey cpk: Encrypts the data on the service-side with the given key. Use of customer-provided keys must be done over HTTPS. diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/blob_service_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/blob_service_client.py index de298072a45e..af9fc771b3be 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/blob_service_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/blob_service_client.py @@ -550,15 +550,11 @@ def delete_container( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/container_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/container_client.py index 15e9012f9b7c..99651c8566e3 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/container_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/container_client.py @@ -31,10 +31,9 @@ return_headers_and_deserialized) from ._generated import AzureBlobStorage from ._generated.models import ( - ModifiedAccessConditions, StorageErrorException, SignedIdentifier) -from ._deserialize import deserialize_container_properties +from ._deserialize import deserialize_container_properties, get_modify_conditions from .models import ( # pylint: disable=unused-import ContainerProperties, BlobProperties, @@ -389,15 +388,11 @@ def delete_container( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None @@ -413,11 +408,7 @@ def delete_container( """ lease = kwargs.pop('lease', None) access_conditions = get_access_conditions(lease) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) timeout = kwargs.pop('timeout', None) try: self._client.container.delete( @@ -459,15 +450,11 @@ def acquire_lease( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :returns: A LeaseClient object, that can be run in a context manager. @@ -582,7 +569,7 @@ def set_container_metadata( # type: ignore headers.update(add_metadata_headers(metadata)) lease = kwargs.pop('lease', None) access_conditions = get_access_conditions(lease) - mod_conditions = ModifiedAccessConditions(if_modified_since=kwargs.pop('if_modified_since', None)) + mod_conditions = get_modify_conditions(kwargs) timeout = kwargs.pop('timeout', None) try: return self._client.container.set_metadata( # type: ignore @@ -693,9 +680,7 @@ def set_container_access_policy( identifiers.append(SignedIdentifier(id=key, access_policy=value)) # type: ignore signed_identifiers = identifiers # type: ignore lease = kwargs.pop('lease', None) - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None)) + mod_conditions = get_modify_conditions(kwargs) access_conditions = get_access_conditions(lease) timeout = kwargs.pop('timeout', None) try: @@ -855,15 +840,11 @@ def upload_blob( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. This method may make multiple calls to the Azure service and the timeout will apply to @@ -963,15 +944,11 @@ def delete_blob( If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None @@ -1088,15 +1065,11 @@ def delete_blobs(self, *blobs, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :return: An iterator of responses, one for each blob in order diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/lease.py b/sdk/storage/azure-storage-blob/azure/storage/blob/lease.py index 0ed9d8aa05f0..386050a1989c 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/lease.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/lease.py @@ -14,10 +14,8 @@ from azure.core.tracing.decorator import distributed_trace from ._shared.response_handlers import return_response_headers, process_storage_error -from ._generated.models import ( - StorageErrorException, - ModifiedAccessConditions, - LeaseAccessConditions) +from ._generated.models import StorageErrorException, LeaseAccessConditions +from ._deserialize import get_modify_conditions if TYPE_CHECKING: from datetime import datetime @@ -103,24 +101,16 @@ def acquire(self, lease_duration=-1, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :rtype: None """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = self._client.acquire_lease( timeout=kwargs.pop('timeout', None), @@ -158,24 +148,16 @@ def renew(self, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :return: None """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = self._client.renew_lease( lease_id=self.id, @@ -210,24 +192,16 @@ def release(self, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :return: None """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = self._client.release_lease( lease_id=self.id, @@ -261,24 +235,16 @@ def change(self, proposed_lease_id, **kwargs): If a date is passed in without timezone info, it is assumed to be UTC. Specify this header to perform the operation only if the resource has not been modified since the specified date/time. - :keyword str if_match: - An ETag value, or the wildcard character (*). Specify this header to perform - the operation only if the resource's ETag matches the value specified. - :keyword str if_none_match: - An ETag value, or the wildcard character (*). Specify this header - to perform the operation only if the resource's ETag does not match - the value specified. Specify the wildcard character (*) to perform - the operation only if the resource does not exist, and fail the - operation if it does exist. + :keyword str etag: + An ETag value, or the wildcard character (*). Used to check if the resource has changed, + and act according to the condition specified by the `match_condition` parameter. + :keyword :class:`MatchConditions` match_condition: + The match condition to use upon the etag. :keyword int timeout: The timeout parameter is expressed in seconds. :return: None """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=kwargs.pop('if_match', None), - if_none_match=kwargs.pop('if_none_match', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = self._client.change_lease( lease_id=self.id, @@ -332,9 +298,7 @@ def break_lease(self, lease_break_period=None, **kwargs): :return: Approximate time remaining in the lease period, in seconds. :rtype: int """ - mod_conditions = ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None)) + mod_conditions = get_modify_conditions(kwargs) try: response = self._client.break_lease( timeout=kwargs.pop('timeout', None), From b4dd780047e1716ed861bade4813dd71c41f0b92 Mon Sep 17 00:00:00 2001 From: antisch Date: Fri, 18 Oct 2019 14:58:49 -0700 Subject: [PATCH 2/7] Process conditional headers --- .../azure/storage/blob/_deserialize.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py index cd41c59baf88..fabed8e30de4 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py @@ -5,7 +5,10 @@ # -------------------------------------------------------------------------- # pylint: disable=no-self-use +from azure.core import MatchConditions + from ._shared.response_handlers import deserialize_metadata +from ._generated.models import ModifiedAccessConditions, SourceModifiedAccessConditions from .models import BlobProperties, ContainerProperties @@ -47,3 +50,47 @@ def get_page_ranges_result(ranges): if ranges.clear_range: clear_range = [{'start': b.start, 'end': b.end} for b in ranges.clear_range] return page_range, clear_range # type: ignore + + +def get_modify_conditions(kwargs): + # type: (Dict[str, Any]) -> ModifiedAccessConditions + if_match = None + if_none_match = None + match_condition = kwargs.pop('match_condition', None) + if match_condition == MatchConditions.IfNotModified: + if_match = kwargs.pop('etag', None) + elif match_condition == MatchConditions.IfPresent: + if_match = '*' + elif match_condition == MatchConditions.IfModified: + if_none_match = kwargs.pop('etag', None) + elif match_condition == MatchConditions.IfMissing: + if_none_match = '*' + + return ModifiedAccessConditions( + if_modified_since=kwargs.pop('if_modified_since', None), + if_unmodified_since=kwargs.pop('if_unmodified_since', None), + if_match=if_match or kwargs.pop('if_match', None), + if_none_match=if_none_match or kwargs.pop('if_none_match', None) + ) + + +def get_source_conditions(kwargs): + # type: (Dict[str, Any]) -> SourceModifiedAccessConditions + if_match = None + if_none_match = None + match_condition = kwargs.pop('source_match_condition', None) + if match_condition == MatchConditions.IfNotModified: + if_match = kwargs.pop('source_etag', None) + elif match_condition == MatchConditions.IfPresent: + if_match = '*' + elif match_condition == MatchConditions.IfModified: + if_none_match = kwargs.pop('source_etag', None) + elif match_condition == MatchConditions.IfMissing: + if_none_match = '*' + + return SourceModifiedAccessConditions( + source_if_modified_since=kwargs.pop('source_if_modified_since', None), + source_if_unmodified_since=kwargs.pop('source_if_unmodified_since', None), + source_if_match=if_match or kwargs.pop('source_if_match', None), + source_if_none_match=if_none_match or kwargs.pop('source_if_none_match', None) + ) From bec5f6287100e6a721f7971152e546be969bad43 Mon Sep 17 00:00:00 2001 From: antisch Date: Fri, 18 Oct 2019 14:59:34 -0700 Subject: [PATCH 3/7] Updated tests --- .../tests/test_append_blob.py | 24 ++-- .../tests/test_append_blob_async.py | 25 ++-- .../tests/test_blob_access_conditions.py | 119 +++++++++--------- .../test_blob_access_conditions_async.py | 116 ++++++++--------- .../tests/test_page_blob.py | 41 +++--- .../tests/test_page_blob_async.py | 59 ++++----- 6 files changed, 209 insertions(+), 175 deletions(-) diff --git a/sdk/storage/azure-storage-blob/tests/test_append_blob.py b/sdk/storage/azure-storage-blob/tests/test_append_blob.py index c965f80f7e63..2f16dc7c76e8 100644 --- a/sdk/storage/azure-storage-blob/tests/test_append_blob.py +++ b/sdk/storage/azure-storage-blob/tests/test_append_blob.py @@ -11,6 +11,7 @@ import unittest from datetime import datetime, timedelta +from azure.core import MatchConditions from azure.core.exceptions import ResourceNotFoundError, ResourceModifiedError, HttpResponseError from azure.storage.blob import ( BlobServiceClient, @@ -359,7 +360,8 @@ def test_append_block_from_url_with_source_if_match(self): resp = destination_blob_client. \ append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - source_if_match=source_blob_properties.get('etag')) + source_etag=source_blob_properties.get('etag'), + source_match_condition=MatchConditions.IfNotModified) self.assertEqual(resp.get('blob_append_offset'), '0') self.assertEqual(resp.get('blob_committed_block_count'), 1) self.assertIsNotNone(resp.get('etag')) @@ -376,7 +378,8 @@ def test_append_block_from_url_with_source_if_match(self): with self.assertRaises(ResourceNotFoundError): destination_blob_client.append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - source_if_match='0x111111111111111') + source_etag='0x111111111111111', + source_match_condition=MatchConditions.IfNotModified) @record def test_append_block_from_url_with_source_if_none_match(self): @@ -395,7 +398,8 @@ def test_append_block_from_url_with_source_if_none_match(self): resp = destination_blob_client. \ append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - source_if_none_match='0x111111111111111') + source_etag='0x111111111111111', + source_match_condition=MatchConditions.IfModified) self.assertEqual(resp.get('blob_append_offset'), '0') self.assertEqual(resp.get('blob_committed_block_count'), 1) self.assertIsNotNone(resp.get('etag')) @@ -412,7 +416,8 @@ def test_append_block_from_url_with_source_if_none_match(self): with self.assertRaises(ResourceNotFoundError): destination_blob_client.append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - source_if_none_match=source_blob_properties.get('etag')) + source_etag=source_blob_properties.get('etag'), + source_match_condition=MatchConditions.IfModified) @record def test_append_block_from_url_with_if_match(self): @@ -434,7 +439,8 @@ def test_append_block_from_url_with_if_match(self): resp = destination_blob_client. \ append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - if_match=destination_blob_properties_on_creation.get('etag')) + etag=destination_blob_properties_on_creation.get('etag'), + match_condition=MatchConditions.IfNotModified) self.assertEqual(resp.get('blob_append_offset'), '0') self.assertEqual(resp.get('blob_committed_block_count'), 1) self.assertIsNotNone(resp.get('etag')) @@ -451,7 +457,8 @@ def test_append_block_from_url_with_if_match(self): with self.assertRaises(ResourceModifiedError): destination_blob_client.append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - if_match='0x111111111111111') + etag='0x111111111111111', + match_condition=MatchConditions.IfNotModified) @record def test_append_block_from_url_with_if_none_match(self): @@ -469,7 +476,7 @@ def test_append_block_from_url_with_if_none_match(self): resp = destination_blob_client. \ append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - if_none_match='0x111111111111111') + etag='0x111111111111111', match_condition=MatchConditions.IfModified) self.assertEqual(resp.get('blob_append_offset'), '0') self.assertEqual(resp.get('blob_committed_block_count'), 1) self.assertIsNotNone(resp.get('etag')) @@ -486,7 +493,8 @@ def test_append_block_from_url_with_if_none_match(self): with self.assertRaises(ResourceModifiedError): destination_blob_client.append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - if_none_match=destination_blob_properties.get('etag')) + etag=destination_blob_properties.get('etag'), + match_condition=MatchConditions.IfModified) @record def test_append_block_from_url_with_maxsize_condition(self): diff --git a/sdk/storage/azure-storage-blob/tests/test_append_blob_async.py b/sdk/storage/azure-storage-blob/tests/test_append_blob_async.py index 0cfd5b560ad4..87c20e94495f 100644 --- a/sdk/storage/azure-storage-blob/tests/test_append_blob_async.py +++ b/sdk/storage/azure-storage-blob/tests/test_append_blob_async.py @@ -13,7 +13,7 @@ import os import unittest -from azure.core import HttpResponseError +from azure.core import HttpResponseError, MatchConditions from azure.core.exceptions import ResourceNotFoundError, ResourceModifiedError from azure.core.pipeline.transport import AioHttpTransport from multidict import CIMultiDict, CIMultiDictProxy @@ -437,7 +437,8 @@ async def _test_append_block_from_url_with_source_if_match(self): resp = await destination_blob_client. \ append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - source_if_match=source_properties.get('etag')) + source_etag=source_properties.get('etag'), + source_match_condition=MatchConditions.IfNotModified) self.assertEqual(resp.get('blob_append_offset'), '0') self.assertEqual(resp.get('blob_committed_block_count'), 1) self.assertIsNotNone(resp.get('etag')) @@ -454,7 +455,8 @@ async def _test_append_block_from_url_with_source_if_match(self): await destination_blob_client.append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - source_if_match='0x111111111111111') + source_etag='0x111111111111111', + source_match_condition=MatchConditions.IfNotModified) @record def test_append_block_from_url_with_source_if_match_async(self): @@ -478,7 +480,8 @@ async def _test_append_block_from_url_with_source_if_none_match(self): resp = await destination_blob_client. \ append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - source_if_none_match='0x111111111111111') + source_etag='0x111111111111111', + source_match_condition=MatchConditions.IfModified) self.assertEqual(resp.get('blob_append_offset'), '0') self.assertEqual(resp.get('blob_committed_block_count'), 1) self.assertIsNotNone(resp.get('etag')) @@ -495,7 +498,8 @@ async def _test_append_block_from_url_with_source_if_none_match(self): await destination_blob_client.append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - source_if_none_match=source_properties.get('etag')) + source_etag=source_properties.get('etag'), + source_match_conditions=MatchConditions.IfModified) @record def test_append_block_from_url_with_source_if_none_match_async(self): @@ -522,7 +526,8 @@ async def _test_append_block_from_url_with_if_match(self): resp = await destination_blob_client. \ append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - if_match=destination_blob_properties_on_creation.get('etag')) + etag=destination_blob_properties_on_creation.get('etag'), + match_condition=MatchConditions.IfNotModified) self.assertEqual(resp.get('blob_append_offset'), '0') self.assertEqual(resp.get('blob_committed_block_count'), 1) self.assertIsNotNone(resp.get('etag')) @@ -539,7 +544,8 @@ async def _test_append_block_from_url_with_if_match(self): await destination_blob_client.append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - if_match='0x111111111111111') + etag='0x111111111111111', + match_condition=MatchConditions.IfNotModified) @record def test_append_block_from_url_with_if_match_async(self): @@ -562,7 +568,7 @@ async def _test_append_block_from_url_with_if_none_match(self): resp = await destination_blob_client. \ append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - if_none_match='0x111111111111111') + etag='0x111111111111111', match_condition=MatchConditions.IfModified) self.assertEqual(resp.get('blob_append_offset'), '0') self.assertEqual(resp.get('blob_committed_block_count'), 1) self.assertIsNotNone(resp.get('etag')) @@ -580,7 +586,8 @@ async def _test_append_block_from_url_with_if_none_match(self): await destination_blob_client.append_block_from_url(source_blob_client.url + '?' + sas, source_offset=0, source_length=LARGE_BLOB_SIZE, - if_none_match=destination_blob_properties.get('etag')) + etag=destination_blob_properties.get('etag'), + match_condition=MatchConditions.IfModified) @record def test_append_block_from_url_with_if_none_match_async(self): diff --git a/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py b/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py index aff426ffe27c..eceee4511f61 100644 --- a/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py +++ b/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py @@ -11,6 +11,7 @@ import os import unittest +from azure.core import MatchConditions from azure.core.exceptions import HttpResponseError, ResourceNotFoundError, ResourceModifiedError from azure.storage.blob import ( @@ -361,7 +362,7 @@ def test_put_blob_with_if_match(self): etag = blob.get_blob_properties().etag # Act - resp = blob.upload_blob(data, length=len(data), if_match=etag) + resp = blob.upload_blob(data, length=len(data), etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertIsNotNone(resp.get('etag')) @@ -375,7 +376,12 @@ def test_put_blob_with_if_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.upload_blob(data, length=len(data), if_match='0x111111111111111', overwrite=True) + blob.upload_blob( + data, + length=len(data), + etag='0x111111111111111', + match_condition=MatchConditions.IfNotModified, + overwrite=True) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -388,7 +394,7 @@ def test_put_blob_with_if_none_match(self): self.container_name, 'blob1', data) # Act - resp = blob.upload_blob(data, length=len(data), if_none_match='0x111111111111111') + resp = blob.upload_blob(data, length=len(data), etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertIsNotNone(resp.get('etag')) @@ -403,7 +409,7 @@ def test_put_blob_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.upload_blob(data, length=len(data), if_none_match=etag, overwrite=True) + blob.upload_blob(data, length=len(data), etag=etag, match_condition=MatchConditions.IfModified, overwrite=True) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -476,7 +482,7 @@ def test_get_blob_with_if_match(self): etag = blob.get_blob_properties().etag # Act - content = blob.download_blob(if_match=etag) + content = blob.download_blob(etag=etag, match_condition=MatchConditions.IfNotModified) content = b"".join(list(content)) # Assert @@ -490,7 +496,7 @@ def test_get_blob_with_if_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.download_blob(if_match='0x111111111111111') + blob.download_blob(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -502,7 +508,7 @@ def test_get_blob_with_if_none_match(self): self.container_name, 'blob1', b'hello world') # Act - content = blob.download_blob(if_none_match='0x111111111111111') + content = blob.download_blob(etag='0x111111111111111', match_condition=MatchConditions.IfModified) content = b"".join(list(content)) # Assert @@ -517,7 +523,7 @@ def test_get_blob_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.download_blob(if_none_match=etag) + blob.download_blob(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -608,7 +614,7 @@ def test_set_blob_properties_with_if_match(self): content_settings = ContentSettings( content_language='spanish', content_disposition='inline') - blob.set_http_headers(content_settings, if_match=etag) + blob.set_http_headers(content_settings, etag=etag, match_condition=MatchConditions.IfNotModified) # Assert properties = blob.get_blob_properties() @@ -627,7 +633,7 @@ def test_set_blob_properties_with_if_match_fail(self): content_language='spanish', content_disposition='inline') blob = self.bsc.get_blob_client(self.container_name, 'blob1') - blob.set_http_headers(content_settings, if_match='0x111111111111111') + blob.set_http_headers(content_settings, etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -643,7 +649,7 @@ def test_set_blob_properties_with_if_none_match(self): content_language='spanish', content_disposition='inline') blob = self.bsc.get_blob_client(self.container_name, 'blob1') - blob.set_http_headers(content_settings, if_none_match='0x111111111111111') + blob.set_http_headers(content_settings, etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert properties = blob.get_blob_properties() @@ -663,7 +669,7 @@ def test_set_blob_properties_with_if_none_match_fail(self): content_settings = ContentSettings( content_language='spanish', content_disposition='inline') - blob.set_http_headers(content_settings, if_none_match=etag) + blob.set_http_headers(content_settings, etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -741,7 +747,7 @@ def test_get_blob_properties_with_if_match(self): etag = blob.get_blob_properties().etag # Act - properties = blob.get_blob_properties(if_match=etag) + properties = blob.get_blob_properties(etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertIsNotNone(properties) @@ -758,7 +764,7 @@ def test_get_blob_properties_with_if_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: blob = self.bsc.get_blob_client(self.container_name, 'blob1') - blob.get_blob_properties(if_match='0x111111111111111') + blob.get_blob_properties(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -771,7 +777,7 @@ def test_get_blob_properties_with_if_none_match(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - properties = blob.get_blob_properties(if_none_match='0x111111111111111') + properties = blob.get_blob_properties(etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertIsNotNone(properties) @@ -789,7 +795,7 @@ def test_get_blob_properties_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.get_blob_properties(if_none_match=etag) + blob.get_blob_properties(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -865,7 +871,7 @@ def test_get_blob_metadata_with_if_match(self): etag = blob.get_blob_properties().etag # Act - md = blob.get_blob_properties(if_match=etag).metadata + md = blob.get_blob_properties(etag=etag, match_condition=MatchConditions.IfNotModified).metadata # Assert self.assertIsNotNone(md) @@ -879,7 +885,7 @@ def test_get_blob_metadata_with_if_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: blob = self.bsc.get_blob_client(self.container_name, 'blob1') - blob.get_blob_properties(if_match='0x111111111111111').metadata + blob.get_blob_properties(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified).metadata # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -892,7 +898,7 @@ def test_get_blob_metadata_with_if_none_match(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - md = blob.get_blob_properties(if_none_match='0x111111111111111').metadata + md = blob.get_blob_properties(etag='0x111111111111111', match_condition=MatchConditions.IfModified).metadata # Assert self.assertIsNotNone(md) @@ -907,7 +913,7 @@ def test_get_blob_metadata_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.get_blob_properties(if_none_match=etag).metadata + blob.get_blob_properties(etag=etag, match_condition=MatchConditions.IfModified).metadata # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -990,7 +996,7 @@ def test_set_blob_metadata_with_if_match(self): # Act metadata = {'hello': 'world', 'number': '42'} - blob.set_blob_metadata(metadata, if_match=etag) + blob.set_blob_metadata(metadata, etag=etag, match_condition=MatchConditions.IfNotModified) # Assert md = blob.get_blob_properties().metadata @@ -1006,7 +1012,7 @@ def test_set_blob_metadata_with_if_match_fail(self): with self.assertRaises(ResourceModifiedError) as e: metadata = {'hello': 'world', 'number': '42'} blob = self.bsc.get_blob_client(self.container_name, 'blob1') - blob.set_blob_metadata(metadata, if_match='0x111111111111111') + blob.set_blob_metadata(metadata, etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1020,7 +1026,7 @@ def test_set_blob_metadata_with_if_none_match(self): # Act metadata = {'hello': 'world', 'number': '42'} blob = self.bsc.get_blob_client(self.container_name, 'blob1') - blob.set_blob_metadata(metadata, if_none_match='0x111111111111111') + blob.set_blob_metadata(metadata, etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert md = blob.get_blob_properties().metadata @@ -1037,7 +1043,7 @@ def test_set_blob_metadata_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: metadata = {'hello': 'world', 'number': '42'} - blob.set_blob_metadata(metadata, if_none_match=etag) + blob.set_blob_metadata(metadata, etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1114,7 +1120,7 @@ def test_delete_blob_with_if_match(self): # Act - resp = blob.delete_blob(if_match=etag) + resp = blob.delete_blob(etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertIsNone(resp) @@ -1128,7 +1134,7 @@ def test_delete_blob_with_if_match_fail(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') with self.assertRaises(ResourceModifiedError) as e: - blob.delete_blob(if_match='0x111111111111111') + blob.delete_blob(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1141,7 +1147,7 @@ def test_delete_blob_with_if_none_match(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - resp = blob.delete_blob(if_none_match='0x111111111111111') + resp = blob.delete_blob(etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertIsNone(resp) @@ -1156,7 +1162,7 @@ def test_delete_blob_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.delete_blob(if_none_match=etag) + blob.delete_blob(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1234,7 +1240,7 @@ def test_snapshot_blob_with_if_match(self): etag = blob.get_blob_properties().etag # Act - resp = blob.create_snapshot(if_match=etag) + resp = blob.create_snapshot(etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertIsNotNone(resp) @@ -1249,7 +1255,7 @@ def test_snapshot_blob_with_if_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: blob = self.bsc.get_blob_client(self.container_name, 'blob1') - blob.create_snapshot(if_match='0x111111111111111') + blob.create_snapshot(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1262,7 +1268,7 @@ def test_snapshot_blob_with_if_none_match(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - resp = blob.create_snapshot(if_none_match='0x111111111111111') + resp = blob.create_snapshot(etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertIsNotNone(resp) @@ -1278,7 +1284,7 @@ def test_snapshot_blob_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.create_snapshot(if_none_match=etag) + blob.create_snapshot(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1369,7 +1375,7 @@ def test_lease_blob_with_if_match(self): # Act lease = blob.acquire_lease( lease_id=test_lease_id, - if_match=etag) + etag=etag, match_condition=MatchConditions.IfNotModified) lease.break_lease() @@ -1386,7 +1392,7 @@ def test_lease_blob_with_if_match_fail(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') with self.assertRaises(ResourceModifiedError) as e: - blob.acquire_lease(if_match='0x111111111111111') + blob.acquire_lease(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1402,7 +1408,8 @@ def test_lease_blob_with_if_none_match(self): blob = self.bsc.get_blob_client(self.container_name, 'blob1') lease = blob.acquire_lease( lease_id=test_lease_id, - if_none_match='0x111111111111111') + etag='0x111111111111111', + match_condition=MatchConditions.IfModified) lease.break_lease() @@ -1420,7 +1427,7 @@ def test_lease_blob_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.acquire_lease(if_none_match=etag) + blob.acquire_lease(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1515,7 +1522,7 @@ def test_put_block_list_with_if_match(self): # Act block_list = [BlobBlock(block_id='1'), BlobBlock(block_id='2'), BlobBlock(block_id='3')] - blob.commit_block_list(block_list, if_match=etag) + blob.commit_block_list(block_list, etag=etag, match_condition=MatchConditions.IfNotModified) # Assert content = blob.download_blob() @@ -1534,7 +1541,7 @@ def test_put_block_list_with_if_match_fail(self): with self.assertRaises(ResourceModifiedError) as e: blob.commit_block_list( [BlobBlock(block_id='1'), BlobBlock(block_id='2'), BlobBlock(block_id='3')], - if_match='0x111111111111111') + etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1550,7 +1557,7 @@ def test_put_block_list_with_if_none_match(self): # Act block_list = [BlobBlock(block_id='1'), BlobBlock(block_id='2'), BlobBlock(block_id='3')] - blob.commit_block_list(block_list, if_none_match='0x111111111111111') + blob.commit_block_list(block_list, etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert content = blob.download_blob() @@ -1569,7 +1576,7 @@ def test_put_block_list_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: block_list = [BlobBlock(block_id='1'), BlobBlock(block_id='2'), BlobBlock(block_id='3')] - blob.commit_block_list(block_list, if_none_match=etag) + blob.commit_block_list(block_list, etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1648,7 +1655,7 @@ def test_update_page_with_if_match(self): etag = blob.get_blob_properties().etag # Act - blob.upload_page(data, offset=0, length=512, if_match=etag) + blob.upload_page(data, offset=0, length=512, etag=etag, match_condition=MatchConditions.IfNotModified) # Assert @@ -1662,7 +1669,7 @@ def test_update_page_with_if_match_fail(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') with self.assertRaises(ResourceModifiedError) as e: - blob.upload_page(data, offset=0, length=512, if_match='0x111111111111111') + blob.upload_page(data, offset=0, length=512, etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1676,7 +1683,7 @@ def test_update_page_with_if_none_match(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - blob.upload_page(data, offset=0, length=512, if_none_match='0x111111111111111') + blob.upload_page(data, offset=0, length=512, etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert @@ -1691,7 +1698,7 @@ def test_update_page_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.upload_page(data, offset=0, length=512, if_none_match=etag) + blob.upload_page(data, offset=0, length=512, etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1781,7 +1788,7 @@ def test_get_page_ranges_iter_with_if_match(self): etag = blob.get_blob_properties().etag # Act - ranges = blob.get_page_ranges(if_match=etag) + ranges = blob.get_page_ranges(etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(len(ranges[0]), 2) @@ -1799,7 +1806,7 @@ def test_get_page_ranges_iter_with_if_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.get_page_ranges(if_match='0x111111111111111') + blob.get_page_ranges(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1814,7 +1821,7 @@ def test_get_page_ranges_iter_with_if_none_match(self): blob.upload_page(data, offset=1024, length=512) # Act - ranges = blob.get_page_ranges(if_none_match='0x111111111111111') + ranges = blob.get_page_ranges(etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertEqual(len(ranges[0]), 2) @@ -1834,7 +1841,7 @@ def test_get_page_ranges_iter_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: - blob.get_page_ranges(if_none_match=etag) + blob.get_page_ranges(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1905,7 +1912,7 @@ def test_append_block_with_if_match(self): # Act for i in range(5): etag = blob.get_blob_properties().etag - resp = blob.append_block(u'block {0}'.format(i), if_match=etag) + resp = blob.append_block(u'block {0}'.format(i), etag=etag, match_condition=MatchConditions.IfNotModified) self.assertIsNotNone(resp) # Assert @@ -1920,7 +1927,7 @@ def test_append_block_with_if_match_fail(self): # Act with self.assertRaises(HttpResponseError) as e: for i in range(5): - resp = blob.append_block(u'block {0}'.format(i), if_match='0x111111111111111') + resp = blob.append_block(u'block {0}'.format(i), etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert #self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1932,7 +1939,7 @@ def test_append_block_with_if_none_match(self): # Act for i in range(5): - resp = blob.append_block(u'block {0}'.format(i), if_none_match='0x8D2C9167D53FC2C') + resp = blob.append_block(u'block {0}'.format(i), etag='0x8D2C9167D53FC2C', match_condition=MatchConditions.IfModified) self.assertIsNotNone(resp) # Assert @@ -1948,7 +1955,7 @@ def test_append_block_with_if_none_match_fail(self): with self.assertRaises(ResourceModifiedError) as e: for i in range(5): etag = blob.get_blob_properties().etag - resp = blob.append_block(u'block {0}'.format(i), if_none_match=etag) + resp = blob.append_block(u'block {0}'.format(i), etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2020,7 +2027,7 @@ def test_append_blob_from_bytes_with_if_match(self): # Act data = self.get_random_bytes(LARGE_APPEND_BLOB_SIZE) - blob.upload_blob(data, blob_type=BlobType.AppendBlob, if_match=test_etag) + blob.upload_blob(data, blob_type=BlobType.AppendBlob, etag=test_etag, match_condition=MatchConditions.IfNotModified) # Assert content = b"".join(list(blob.download_blob())) @@ -2036,7 +2043,7 @@ def test_append_blob_from_bytes_with_if_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: data = self.get_random_bytes(LARGE_APPEND_BLOB_SIZE) - blob.upload_blob(data, blob_type=BlobType.AppendBlob, if_match=test_etag) + blob.upload_blob(data, blob_type=BlobType.AppendBlob, etag=test_etag, match_condition=MatchConditions.IfNotModified) self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2049,7 +2056,7 @@ def test_append_blob_from_bytes_with_if_none_match(self): # Act data = self.get_random_bytes(LARGE_APPEND_BLOB_SIZE) - blob.upload_blob(data, blob_type=BlobType.AppendBlob, if_none_match=test_etag) + blob.upload_blob(data, blob_type=BlobType.AppendBlob, etag=test_etag, match_condition=MatchConditions.IfModified) # Assert content = b"".join(list(blob.download_blob())) @@ -2065,7 +2072,7 @@ def test_append_blob_from_bytes_with_if_none_match_fail(self): # Act with self.assertRaises(ResourceModifiedError) as e: data = self.get_random_bytes(LARGE_APPEND_BLOB_SIZE) - blob.upload_blob(data, blob_type=BlobType.AppendBlob, if_none_match=test_etag) + blob.upload_blob(data, blob_type=BlobType.AppendBlob, etag=test_etag, match_condition=MatchConditions.IfModified) self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) diff --git a/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions_async.py b/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions_async.py index df0fa22d4748..98d90b8871ee 100644 --- a/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions_async.py +++ b/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions_async.py @@ -12,6 +12,7 @@ import os import unittest +from azure.core import MatchConditions from azure.core.exceptions import HttpResponseError, ResourceNotFoundError, ResourceModifiedError from azure.core.pipeline.transport import AioHttpTransport from multidict import CIMultiDict, CIMultiDictProxy @@ -449,7 +450,7 @@ async def _test_put_blob_with_if_match_async(self): etag = (await blob.get_blob_properties()).etag # Act - resp = await blob.upload_blob(data, length=len(data), if_match=etag) + resp = await blob.upload_blob(data, length=len(data), etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertIsNotNone(resp.get('etag')) @@ -467,7 +468,9 @@ async def _test_put_blob_with_if_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.upload_blob(data, length=len(data), if_match='0x111111111111111', overwrite=True) + await blob.upload_blob( + data, length=len(data), etag='0x111111111111111', + match_condition=MatchConditions.IfNotModified, overwrite=True) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -484,7 +487,7 @@ async def _test_put_blob_with_if_none_match_async(self): self.container_name, 'blob1', data) # Act - resp = await blob.upload_blob(data, length=len(data), if_none_match='0x111111111111111') + resp = await blob.upload_blob(data, length=len(data), etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertIsNotNone(resp.get('etag')) @@ -503,7 +506,7 @@ async def _test_put_blob_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.upload_blob(data, length=len(data), if_none_match=etag, overwrite=True) + await blob.upload_blob(data, length=len(data), etag=etag, match_condition=MatchConditions.IfModified, overwrite=True) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -596,7 +599,7 @@ async def _test_get_blob_with_if_match_async(self): etag = (await blob.get_blob_properties()).etag # Act - content = await blob.download_blob(if_match=etag) + content = await blob.download_blob(etag=etag, match_condition=MatchConditions.IfNotModified) content = await content.content_as_bytes() # Assert @@ -614,7 +617,7 @@ async def _test_get_blob_with_if_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.download_blob(if_match='0x111111111111111') + await blob.download_blob(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -630,7 +633,7 @@ async def _test_get_blob_with_if_none_match_async(self): self.container_name, 'blob1', b'hello world') # Act - content = await blob.download_blob(if_none_match='0x111111111111111') + content = await blob.download_blob(etag='0x111111111111111', match_condition=MatchConditions.IfModified) content = await content.content_as_bytes() # Assert @@ -649,7 +652,7 @@ async def _test_get_blob_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.download_blob(if_none_match=etag) + await blob.download_blob(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -760,7 +763,7 @@ async def _test_set_blob_properties_with_if_match_async(self): content_settings = ContentSettings( content_language='spanish', content_disposition='inline') - await blob.set_http_headers(content_settings, if_match=etag) + await blob.set_http_headers(content_settings, etag=etag, match_condition=MatchConditions.IfNotModified) # Assert properties = await blob.get_blob_properties() @@ -783,7 +786,7 @@ async def _test_set_blob_properties_with_if_match_fail_async(self): content_language='spanish', content_disposition='inline') blob = self.bsc.get_blob_client(self.container_name, 'blob1') - await blob.set_http_headers(content_settings, if_match='0x111111111111111') + await blob.set_http_headers(content_settings, etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -803,7 +806,7 @@ async def _test_set_blob_properties_with_if_none_match_async(self): content_language='spanish', content_disposition='inline') blob = self.bsc.get_blob_client(self.container_name, 'blob1') - await blob.set_http_headers(content_settings, if_none_match='0x111111111111111') + await blob.set_http_headers(content_settings, etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert properties = await blob.get_blob_properties() @@ -827,7 +830,7 @@ async def _test_set_blob_properties_with_if_none_match_fail_async(self): content_settings = ContentSettings( content_language='spanish', content_disposition='inline') - await blob.set_http_headers(content_settings, if_none_match=etag) + await blob.set_http_headers(content_settings, etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -925,7 +928,7 @@ async def _test_get_blob_properties_with_if_match_async(self): etag = (await blob.get_blob_properties()).etag # Act - properties = await blob.get_blob_properties(if_match=etag) + properties = await blob.get_blob_properties(etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertIsNotNone(properties) @@ -946,7 +949,7 @@ async def _test_get_blob_properties_with_if_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: blob = self.bsc.get_blob_client(self.container_name, 'blob1') - await blob.get_blob_properties(if_match='0x111111111111111') + await blob.get_blob_properties(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -963,7 +966,7 @@ async def _test_get_blob_properties_with_if_none_match_async(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - properties = await blob.get_blob_properties(if_none_match='0x111111111111111') + properties = await blob.get_blob_properties(etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertIsNotNone(properties) @@ -985,7 +988,7 @@ async def _test_get_blob_properties_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.get_blob_properties(if_none_match=etag) + await blob.get_blob_properties(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1081,7 +1084,7 @@ async def _test_get_blob_metadata_with_if_match_async(self): etag = (await blob.get_blob_properties()).etag # Act - md = (await blob.get_blob_properties(if_match=etag)).metadata + md = (await blob.get_blob_properties(etag=etag, match_condition=MatchConditions.IfNotModified)).metadata # Assert self.assertIsNotNone(md) @@ -1099,7 +1102,7 @@ async def _test_get_blob_metadata_with_if_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: blob = self.bsc.get_blob_client(self.container_name, 'blob1') - await blob.get_blob_properties(if_match='0x111111111111111') + await blob.get_blob_properties(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1116,7 +1119,7 @@ async def _test_get_blob_metadata_with_if_none_match_async(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - md = (await blob.get_blob_properties(if_none_match='0x111111111111111')).metadata + md = (await blob.get_blob_properties(etag='0x111111111111111', match_condition=MatchConditions.IfModified)).metadata # Assert self.assertIsNotNone(md) @@ -1135,7 +1138,7 @@ async def _test_get_blob_metadata_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.get_blob_properties(if_none_match=etag) + await blob.get_blob_properties(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1238,7 +1241,7 @@ async def _test_set_blob_metadata_with_if_match_async(self): # Act metadata = {'hello': 'world', 'number': '42'} - await blob.set_blob_metadata(metadata, if_match=etag) + await blob.set_blob_metadata(metadata, etag=etag, match_condition=MatchConditions.IfNotModified) # Assert md = (await blob.get_blob_properties()).metadata @@ -1258,7 +1261,7 @@ async def _test_set_blob_metadata_with_if_match_fail_async(self): with self.assertRaises(ResourceModifiedError) as e: metadata = {'hello': 'world', 'number': '42'} blob = self.bsc.get_blob_client(self.container_name, 'blob1') - await blob.set_blob_metadata(metadata, if_match='0x111111111111111') + await blob.set_blob_metadata(metadata, etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1276,7 +1279,7 @@ async def _test_set_blob_metadata_with_if_none_match_async(self): # Act metadata = {'hello': 'world', 'number': '42'} blob = self.bsc.get_blob_client(self.container_name, 'blob1') - await blob.set_blob_metadata(metadata, if_none_match='0x111111111111111') + await blob.set_blob_metadata(metadata, etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert md = (await blob.get_blob_properties()).metadata @@ -1297,7 +1300,7 @@ async def _test_set_blob_metadata_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: metadata = {'hello': 'world', 'number': '42'} - await blob.set_blob_metadata(metadata, if_none_match=etag) + await blob.set_blob_metadata(metadata, etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1394,7 +1397,7 @@ async def _test_delete_blob_with_if_match_async(self): # Act - resp = await blob.delete_blob(if_match=etag) + resp = await blob.delete_blob(etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertIsNone(resp) @@ -1412,7 +1415,7 @@ async def _test_delete_blob_with_if_match_fail_async(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') with self.assertRaises(ResourceModifiedError) as e: - await blob.delete_blob(if_match='0x111111111111111') + await blob.delete_blob(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1429,7 +1432,7 @@ async def _test_delete_blob_with_if_none_match_async(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - resp = await blob.delete_blob(if_none_match='0x111111111111111') + resp = await blob.delete_blob(etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertIsNone(resp) @@ -1448,7 +1451,7 @@ async def _test_delete_blob_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.delete_blob(if_none_match=etag) + await blob.delete_blob(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1546,7 +1549,7 @@ async def _test_snapshot_blob_with_if_match_async(self): etag = (await blob.get_blob_properties()).etag # Act - resp = await blob.create_snapshot(if_match=etag) + resp = await blob.create_snapshot(etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertIsNotNone(resp) @@ -1565,7 +1568,7 @@ async def _test_snapshot_blob_with_if_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: blob = self.bsc.get_blob_client(self.container_name, 'blob1') - await blob.create_snapshot(if_match='0x111111111111111') + await blob.create_snapshot(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1582,7 +1585,7 @@ async def _test_snapshot_blob_with_if_none_match_async(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - resp = await blob.create_snapshot(if_none_match='0x111111111111111') + resp = await blob.create_snapshot(etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertIsNotNone(resp) @@ -1602,7 +1605,7 @@ async def _test_snapshot_blob_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.create_snapshot(if_none_match=etag) + await blob.create_snapshot(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1713,7 +1716,7 @@ async def _test_lease_blob_with_if_match_async(self): # Act lease = await blob.acquire_lease( lease_id=test_lease_id, - if_match=etag) + etag=etag, match_condition=MatchConditions.IfNotModified) await lease.break_lease() @@ -1734,7 +1737,7 @@ async def _test_lease_blob_with_if_match_fail_async(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') with self.assertRaises(ResourceModifiedError) as e: - await blob.acquire_lease(if_match='0x111111111111111') + await blob.acquire_lease(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1754,7 +1757,8 @@ async def _test_lease_blob_with_if_none_match_async(self): blob = self.bsc.get_blob_client(self.container_name, 'blob1') lease = await blob.acquire_lease( lease_id=test_lease_id, - if_none_match='0x111111111111111') + etag='0x111111111111111', + match_condition=MatchConditions.IfModified) await lease.break_lease() @@ -1776,7 +1780,7 @@ async def _test_lease_blob_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.acquire_lease(if_none_match=etag) + await blob.acquire_lease(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1898,7 +1902,7 @@ async def _test_put_block_list_with_if_match_async(self): # Act block_list = [BlobBlock(block_id='1'), BlobBlock(block_id='2'), BlobBlock(block_id='3')] - await blob.commit_block_list(block_list, if_match=etag) + await blob.commit_block_list(block_list, etag=etag, match_condition=MatchConditions.IfNotModified) # Assert content = await blob.download_blob() @@ -1923,7 +1927,7 @@ async def _test_put_block_list_with_if_match_fail_async(self): with self.assertRaises(ResourceModifiedError) as e: await blob.commit_block_list( [BlobBlock(block_id='1'), BlobBlock(block_id='2'), BlobBlock(block_id='3')], - if_match='0x111111111111111') + etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -1944,7 +1948,7 @@ async def _test_put_block_list_with_if_none_match_async(self): # Act block_list = [BlobBlock(block_id='1'), BlobBlock(block_id='2'), BlobBlock(block_id='3')] - await blob.commit_block_list(block_list, if_none_match='0x111111111111111') + await blob.commit_block_list(block_list, etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert content = await blob.download_blob() @@ -1969,7 +1973,7 @@ async def _test_put_block_list_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: block_list = [BlobBlock(block_id='1'), BlobBlock(block_id='2'), BlobBlock(block_id='3')] - await blob.commit_block_list(block_list, if_none_match=etag) + await blob.commit_block_list(block_list, etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2068,7 +2072,7 @@ async def _test_update_page_with_if_match_async(self): etag = (await blob.get_blob_properties()).etag # Act - await blob.upload_page(data, offset=0, length=512, if_match=etag) + await blob.upload_page(data, offset=0, length=512, etag=etag, match_condition=MatchConditions.IfNotModified) # Assert @@ -2086,7 +2090,7 @@ async def _test_update_page_with_if_match_fail_async(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') with self.assertRaises(ResourceModifiedError) as e: - await blob.upload_page(data, offset=0, length=512, if_match='0x111111111111111') + await blob.upload_page(data, offset=0, length=512, etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2104,7 +2108,7 @@ async def _test_update_page_with_if_none_match_async(self): # Act blob = self.bsc.get_blob_client(self.container_name, 'blob1') - await blob.upload_page(data, offset=0, length=512, if_none_match='0x111111111111111') + await blob.upload_page(data, offset=0, length=512, etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert @@ -2123,7 +2127,7 @@ async def _test_update_page_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.upload_page(data, offset=0, length=512, if_none_match=etag) + await blob.upload_page(data, offset=0, length=512, etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2228,7 +2232,7 @@ async def _test_get_page_ranges_iter_with_if_match_async(self): etag = (await blob.get_blob_properties()).etag # Act - ranges = await blob.get_page_ranges(if_match=etag) + ranges = await blob.get_page_ranges(etag=etag, match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(len(ranges[0]), 2) @@ -2249,7 +2253,7 @@ async def _test_get_page_ranges_iter_with_if_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.get_page_ranges(if_match='0x111111111111111') + await blob.get_page_ranges(etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2267,7 +2271,7 @@ async def _test_get_page_ranges_iter_with_if_none_match_async(self): await asyncio.gather(blob.upload_page(data, offset=0, length=512), blob.upload_page(data, offset=1024, length=512)) # Act - ranges = await blob.get_page_ranges(if_none_match='0x111111111111111') + ranges = await blob.get_page_ranges(etag='0x111111111111111', match_condition=MatchConditions.IfModified) # Assert self.assertEqual(len(ranges[0]), 2) @@ -2290,7 +2294,7 @@ async def _test_get_page_ranges_iter_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: - await blob.get_page_ranges(if_none_match=etag) + await blob.get_page_ranges(etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2383,7 +2387,7 @@ async def _test_append_block_with_if_match_async(self): # Act for i in range(5): etag = (await blob.get_blob_properties()).etag - resp = await blob.append_block(u'block {0}'.format(i), if_match=etag) + resp = await blob.append_block(u'block {0}'.format(i), etag=etag, match_condition=MatchConditions.IfNotModified) self.assertIsNotNone(resp) # Assert @@ -2403,7 +2407,7 @@ async def _test_append_block_with_if_match_fail_async(self): # Act with self.assertRaises(HttpResponseError) as e: for i in range(5): - resp = await blob.append_block(u'block {0}'.format(i), if_match='0x111111111111111') + resp = await blob.append_block(u'block {0}'.format(i), etag='0x111111111111111', match_condition=MatchConditions.IfNotModified) # Assert #self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2419,7 +2423,7 @@ async def _test_append_block_with_if_none_match_async(self): # Act for i in range(5): - resp = await blob.append_block(u'block {0}'.format(i), if_none_match='0x8D2C9167D53FC2C') + resp = await blob.append_block(u'block {0}'.format(i), etag='0x8D2C9167D53FC2C', match_condition=MatchConditions.IfModified) self.assertIsNotNone(resp) # Assert @@ -2440,7 +2444,7 @@ async def _test_append_block_with_if_none_match_fail_async(self): with self.assertRaises(ResourceModifiedError) as e: for i in range(5): etag = (await blob.get_blob_properties()).etag - resp = await blob.append_block(u'block {0}'.format(i), if_none_match=etag) + resp = await blob.append_block(u'block {0}'.format(i), etag=etag, match_condition=MatchConditions.IfModified) # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2534,7 +2538,7 @@ async def _test_append_blob_from_bytes_with_if_match_async(self): # Act data = self.get_random_bytes(LARGE_APPEND_BLOB_SIZE) - await blob.upload_blob(data, blob_type=BlobType.AppendBlob, if_match=test_etag) + await blob.upload_blob(data, blob_type=BlobType.AppendBlob, etag=test_etag, match_condition=MatchConditions.IfNotModified) # Assert content = await blob.download_blob() @@ -2555,7 +2559,7 @@ async def _test_append_blob_from_bytes_with_if_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: data = self.get_random_bytes(LARGE_APPEND_BLOB_SIZE) - await blob.upload_blob(data, blob_type=BlobType.AppendBlob, if_match=test_etag) + await blob.upload_blob(data, blob_type=BlobType.AppendBlob, etag=test_etag, match_condition=MatchConditions.IfNotModified) self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) @@ -2572,7 +2576,7 @@ async def _test_append_blob_from_bytes_with_if_none_match_async(self): # Act data = self.get_random_bytes(LARGE_APPEND_BLOB_SIZE) - await blob.upload_blob(data, blob_type=BlobType.AppendBlob, if_none_match=test_etag) + await blob.upload_blob(data, blob_type=BlobType.AppendBlob, etag=test_etag, match_condition=MatchConditions.IfModified) # Assert content = await blob.download_blob() @@ -2593,7 +2597,7 @@ async def _test_append_blob_from_bytes_with_if_none_match_fail_async(self): # Act with self.assertRaises(ResourceModifiedError) as e: data = self.get_random_bytes(LARGE_APPEND_BLOB_SIZE) - await blob.upload_blob(data, blob_type=BlobType.AppendBlob, if_none_match=test_etag) + await blob.upload_blob(data, blob_type=BlobType.AppendBlob, etag=test_etag, match_condition=MatchConditions.IfModified) self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) diff --git a/sdk/storage/azure-storage-blob/tests/test_page_blob.py b/sdk/storage/azure-storage-blob/tests/test_page_blob.py index 6cb20eb2671a..1e317828f49d 100644 --- a/sdk/storage/azure-storage-blob/tests/test_page_blob.py +++ b/sdk/storage/azure-storage-blob/tests/test_page_blob.py @@ -11,6 +11,7 @@ import os import unittest from datetime import datetime, timedelta +from azure.core import MatchConditions from azure.core.exceptions import HttpResponseError, ResourceExistsError, ResourceModifiedError from azure.storage.blob import ( @@ -531,7 +532,8 @@ def test_upload_pages_from_url_with_source_if_match(self): offset=0, length=SOURCE_BLOB_SIZE, source_offset=0, - source_if_match=source_properties.get('etag')) + source_etag=source_properties.get('etag'), + source_match_condition=MatchConditions.IfNotModified) self.assertIsNotNone(resp.get('etag')) self.assertIsNotNone(resp.get('last_modified')) @@ -547,7 +549,8 @@ def test_upload_pages_from_url_with_source_if_match(self): .upload_pages_from_url(source_blob_client.url + "?" + sas, offset=0, length=SOURCE_BLOB_SIZE, source_offset=0, - source_if_match='0x111111111111111') + source_etag='0x111111111111111', + source_match_condition=MatchConditions.IfNotModified) @record def test_upload_pages_from_url_with_source_if_none_match(self): @@ -567,7 +570,8 @@ def test_upload_pages_from_url_with_source_if_none_match(self): offset=0, length=SOURCE_BLOB_SIZE, source_offset=0, - source_if_none_match='0x111111111111111') + source_etag='0x111111111111111', + source_match_condition=MatchConditions.IfModified) self.assertIsNotNone(resp.get('etag')) self.assertIsNotNone(resp.get('last_modified')) @@ -583,7 +587,8 @@ def test_upload_pages_from_url_with_source_if_none_match(self): .upload_pages_from_url(source_blob_client.url + "?" + sas, offset=0, length=SOURCE_BLOB_SIZE, source_offset=0, - source_if_none_match=source_properties.get('etag')) + source_etag=source_properties.get('etag'), + source_match_condition=MatchConditions.IfModified) @record def test_upload_pages_from_url_with_if_modified(self): @@ -673,12 +678,10 @@ def test_upload_pages_from_url_with_if_match(self): destination_blob_properties = destination_blob_client.get_blob_properties() # Act: make update page from url calls - resp = destination_blob_client \ - .upload_pages_from_url(source_blob_client.url + "?" + sas, - 0, - SOURCE_BLOB_SIZE, - 0, - if_match=destination_blob_properties.get('etag')) + resp = destination_blob_client.upload_pages_from_url( + source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, + etag=destination_blob_properties.get('etag'), + match_condition=MatchConditions.IfNotModified) self.assertIsNotNone(resp.get('etag')) self.assertIsNotNone(resp.get('last_modified')) @@ -690,11 +693,10 @@ def test_upload_pages_from_url_with_if_match(self): # Act part 2: put block from url with failing condition with self.assertRaises(HttpResponseError): - destination_blob_client \ - .upload_pages_from_url(source_blob_client.url + "?" + sas, 0, - SOURCE_BLOB_SIZE, - 0, - if_match='0x111111111111111') + destination_blob_client.upload_pages_from_url( + source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, + etag='0x111111111111111', + match_condition=MatchConditions.IfNotModified) @record def test_upload_pages_from_url_with_if_none_match(self): @@ -713,7 +715,8 @@ def test_upload_pages_from_url_with_if_none_match(self): 0, SOURCE_BLOB_SIZE, 0, - if_none_match='0x111111111111111') + etag='0x111111111111111', + match_condition=MatchConditions.IfModified) self.assertIsNotNone(resp.get('etag')) self.assertIsNotNone(resp.get('last_modified')) @@ -730,7 +733,8 @@ def test_upload_pages_from_url_with_if_none_match(self): .upload_pages_from_url(source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, - if_none_match=blob_properties.get('etag')) + etag=blob_properties.get('etag'), + match_condition=MatchConditions.IfModified) @record def test_upload_pages_from_url_with_sequence_number_lt(self): @@ -1378,6 +1382,7 @@ def test_incremental_copy_blob(self): @record def test_blob_tier_on_create(self): + pytest.skip("") url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() pbs = BlobServiceClient(url, credential=credential) @@ -1430,6 +1435,7 @@ def test_blob_tier_on_create(self): @record def test_blob_tier_set_tier_api(self): + pytest.skip("") url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() pbs = BlobServiceClient(url, credential=credential) @@ -1481,6 +1487,7 @@ def test_blob_tier_set_tier_api(self): @record def test_blob_tier_copy_blob(self): + pytest.skip("") url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() pbs = BlobServiceClient(url, credential=credential) diff --git a/sdk/storage/azure-storage-blob/tests/test_page_blob_async.py b/sdk/storage/azure-storage-blob/tests/test_page_blob_async.py index 9f123782f9f8..1f3090897adf 100644 --- a/sdk/storage/azure-storage-blob/tests/test_page_blob_async.py +++ b/sdk/storage/azure-storage-blob/tests/test_page_blob_async.py @@ -12,6 +12,7 @@ import unittest from datetime import datetime, timedelta +from azure.core import MatchConditions from azure.core.exceptions import HttpResponseError, ResourceExistsError from azure.core.pipeline.transport import AioHttpTransport from multidict import CIMultiDict, CIMultiDictProxy @@ -649,11 +650,10 @@ async def _test_upload_pages_from_url_with_source_if_match(self): destination_blob_client = await self._create_blob(SOURCE_BLOB_SIZE) # Act: make update page from url calls - resp = await destination_blob_client.upload_pages_from_url(source_blob_client.url + "?" + sas, - 0, - SOURCE_BLOB_SIZE, - 0, - source_if_match=source_properties.get('etag')) + resp = await destination_blob_client.upload_pages_from_url( + source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, + source_etag=source_properties.get('etag'), + source_match_condition=MatchConditions.IfNotModified) self.assertIsNotNone(resp.get('etag')) self.assertIsNotNone(resp.get('last_modified')) @@ -665,10 +665,10 @@ async def _test_upload_pages_from_url_with_source_if_match(self): # Act part 2: put block from url with wrong md5 with self.assertRaises(HttpResponseError): - await destination_blob_client.upload_pages_from_url(source_blob_client.url + "?" + sas, 0, - SOURCE_BLOB_SIZE, - 0, - source_if_match='0x111111111111111') + await destination_blob_client.upload_pages_from_url( + source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, + source_etag='0x111111111111111', + source_match_condition=MatchConditions.IfNotModified) @record def test_upload_pages_from_url_with_source_if_match_async(self): @@ -688,11 +688,9 @@ async def _test_upload_pages_from_url_with_source_if_none_match(self): destination_blob_client = await self._create_blob(SOURCE_BLOB_SIZE) # Act: make update page from url calls - resp = await destination_blob_client.upload_pages_from_url(source_blob_client.url + "?" + sas, - 0, - SOURCE_BLOB_SIZE, - 0, - source_if_none_match='0x111111111111111') + resp = await destination_blob_client.upload_pages_from_url( + source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, + source_etag='0x111111111111111', source_match_condition=MatchConditions.IfModified) self.assertIsNotNone(resp.get('etag')) self.assertIsNotNone(resp.get('last_modified')) @@ -704,10 +702,9 @@ async def _test_upload_pages_from_url_with_source_if_none_match(self): # Act part 2: put block from url with wrong md5 with self.assertRaises(HttpResponseError): - await destination_blob_client.upload_pages_from_url(source_blob_client.url + "?" + sas, 0, - SOURCE_BLOB_SIZE, - 0, - source_if_none_match=source_properties.get('etag')) + await destination_blob_client.upload_pages_from_url( + source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, + source_etag=source_properties.get('etag'), source_match_condition=MatchConditions.IfModified) @record def test_upload_pages_from_url_with_source_if_none_match_async(self): @@ -811,11 +808,10 @@ async def _test_upload_pages_from_url_with_if_match(self): destination_blob_properties = await destination_blob_client.get_blob_properties() # Act: make update page from url calls - resp = await destination_blob_client.upload_pages_from_url(source_blob_client.url + "?" + sas, - 0, - SOURCE_BLOB_SIZE, - 0, - if_match=destination_blob_properties.get('etag')) + resp = await destination_blob_client.upload_pages_from_url( + source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, + etag=destination_blob_properties.get('etag'), + match_condition=MatchConditions.IfNotModified) self.assertIsNotNone(resp.get('etag')) self.assertIsNotNone(resp.get('last_modified')) @@ -827,10 +823,10 @@ async def _test_upload_pages_from_url_with_if_match(self): # Act part 2: put block from url with wrong md5 with self.assertRaises(HttpResponseError): - await destination_blob_client.upload_pages_from_url(source_blob_client.url + "?" + sas, 0, - SOURCE_BLOB_SIZE, - 0, - if_match='0x111111111111111') + await destination_blob_client.upload_pages_from_url( + source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, + etag='0x111111111111111', + match_condition=MatchConditions.IfNotModified) @record def test_upload_pages_from_url_with_if_match_async(self): @@ -853,7 +849,8 @@ async def _test_upload_pages_from_url_with_if_none_match(self): 0, SOURCE_BLOB_SIZE, 0, - if_none_match='0x111111111111111') + etag='0x111111111111111', + match_condition=MatchConditions.IfModified) self.assertIsNotNone(resp.get('etag')) self.assertIsNotNone(resp.get('last_modified')) @@ -868,7 +865,8 @@ async def _test_upload_pages_from_url_with_if_none_match(self): await destination_blob_client.upload_pages_from_url(source_blob_client.url + "?" + sas, 0, SOURCE_BLOB_SIZE, 0, - if_none_match=blob_properties.get('etag')) + etag=blob_properties.get('etag'), + match_condition=MatchConditions.IfModified) @record def test_upload_pages_from_url_with_if_none_match_async(self): @@ -1656,6 +1654,7 @@ def test_incremental_copy_blob(self): async def _test_blob_tier_on_create(self): # Test can only run live + pytest.skip("") if TestMode.need_recording_file(self.test_mode): return @@ -1717,6 +1716,7 @@ def test_blob_tier_on_create(self): loop.run_until_complete(self._test_blob_tier_on_create()) async def _test_blob_tier_set_tier_api(self): + pytest.skip("") await self._setup() url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() @@ -1777,6 +1777,7 @@ def test_blob_tier_set_tier_api(self): loop.run_until_complete(self._test_blob_tier_set_tier_api()) async def _test_blob_tier_copy_blob(self): + pytest.skip("") await self._setup() url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() From 71baba37ae70a9c04a0f41f8ecc4a5d6b3e9c671 Mon Sep 17 00:00:00 2001 From: antisch Date: Fri, 18 Oct 2019 15:33:53 -0700 Subject: [PATCH 4/7] Fixed test --- sdk/storage/azure-storage-blob/tests/test_append_blob_async.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/storage/azure-storage-blob/tests/test_append_blob_async.py b/sdk/storage/azure-storage-blob/tests/test_append_blob_async.py index 87c20e94495f..aacb1c7d0e39 100644 --- a/sdk/storage/azure-storage-blob/tests/test_append_blob_async.py +++ b/sdk/storage/azure-storage-blob/tests/test_append_blob_async.py @@ -499,7 +499,7 @@ async def _test_append_block_from_url_with_source_if_none_match(self): source_offset=0, source_length=LARGE_BLOB_SIZE, source_etag=source_properties.get('etag'), - source_match_conditions=MatchConditions.IfModified) + source_match_condition=MatchConditions.IfModified) @record def test_append_block_from_url_with_source_if_none_match_async(self): From dd6c346e49ed5fc187e2f2c63047b23363b985fc Mon Sep 17 00:00:00 2001 From: antisch Date: Fri, 18 Oct 2019 16:34:06 -0700 Subject: [PATCH 5/7] Updated error scenarios --- .../azure/storage/blob/_deserialize.py | 47 --------------- .../azure/storage/blob/_serialize.py | 57 +++++++++++++++++++ .../storage/blob/aio/blob_client_async.py | 3 +- .../blob/aio/container_client_async.py | 3 +- .../azure/storage/blob/aio/lease_async.py | 2 +- .../azure/storage/blob/blob_client.py | 9 +-- .../azure/storage/blob/container_client.py | 3 +- .../azure/storage/blob/lease.py | 2 +- .../tests/test_blob_access_conditions.py | 9 +++ 9 files changed, 76 insertions(+), 59 deletions(-) create mode 100644 sdk/storage/azure-storage-blob/azure/storage/blob/_serialize.py diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py index fabed8e30de4..cd41c59baf88 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_deserialize.py @@ -5,10 +5,7 @@ # -------------------------------------------------------------------------- # pylint: disable=no-self-use -from azure.core import MatchConditions - from ._shared.response_handlers import deserialize_metadata -from ._generated.models import ModifiedAccessConditions, SourceModifiedAccessConditions from .models import BlobProperties, ContainerProperties @@ -50,47 +47,3 @@ def get_page_ranges_result(ranges): if ranges.clear_range: clear_range = [{'start': b.start, 'end': b.end} for b in ranges.clear_range] return page_range, clear_range # type: ignore - - -def get_modify_conditions(kwargs): - # type: (Dict[str, Any]) -> ModifiedAccessConditions - if_match = None - if_none_match = None - match_condition = kwargs.pop('match_condition', None) - if match_condition == MatchConditions.IfNotModified: - if_match = kwargs.pop('etag', None) - elif match_condition == MatchConditions.IfPresent: - if_match = '*' - elif match_condition == MatchConditions.IfModified: - if_none_match = kwargs.pop('etag', None) - elif match_condition == MatchConditions.IfMissing: - if_none_match = '*' - - return ModifiedAccessConditions( - if_modified_since=kwargs.pop('if_modified_since', None), - if_unmodified_since=kwargs.pop('if_unmodified_since', None), - if_match=if_match or kwargs.pop('if_match', None), - if_none_match=if_none_match or kwargs.pop('if_none_match', None) - ) - - -def get_source_conditions(kwargs): - # type: (Dict[str, Any]) -> SourceModifiedAccessConditions - if_match = None - if_none_match = None - match_condition = kwargs.pop('source_match_condition', None) - if match_condition == MatchConditions.IfNotModified: - if_match = kwargs.pop('source_etag', None) - elif match_condition == MatchConditions.IfPresent: - if_match = '*' - elif match_condition == MatchConditions.IfModified: - if_none_match = kwargs.pop('source_etag', None) - elif match_condition == MatchConditions.IfMissing: - if_none_match = '*' - - return SourceModifiedAccessConditions( - source_if_modified_since=kwargs.pop('source_if_modified_since', None), - source_if_unmodified_since=kwargs.pop('source_if_unmodified_since', None), - source_if_match=if_match or kwargs.pop('source_if_match', None), - source_if_none_match=if_none_match or kwargs.pop('source_if_none_match', None) - ) diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_serialize.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_serialize.py new file mode 100644 index 000000000000..2f21d8b400b0 --- /dev/null +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_serialize.py @@ -0,0 +1,57 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: disable=no-self-use + +from azure.core import MatchConditions + +from ._generated.models import ModifiedAccessConditions, SourceModifiedAccessConditions + + +def _get_match_headers(kwargs, match_param, etag_param): + # type: (str) -> Tuple(Dict[str, Any], Optional[str], Optional[str]) + if_match = None + if_none_match = None + match_condition = kwargs.pop(match_param, None) + if match_condition == MatchConditions.IfNotModified: + if_match = kwargs.pop(etag_param, None) + if not if_match: + raise ValueError("'{}' specified without '{}'.".format(match_param, etag_param)) + elif match_condition == MatchConditions.IfPresent: + if_match = '*' + elif match_condition == MatchConditions.IfModified: + if_none_match = kwargs.pop(etag_param, None) + if not if_none_match: + raise ValueError("'{}' specified without '{}'.".format(match_param, etag_param)) + elif match_condition == MatchConditions.IfMissing: + if_none_match = '*' + elif match_condition is None: + if etag_param in kwargs: + raise ValueError("'{}' specified without '{}'.".format(etag_param, match_param)) + else: + raise TypeError("Invalid match condition: {}".format(match_condition)) + return if_match, if_none_match + + +def get_modify_conditions(kwargs): + # type: (Dict[str, Any]) -> ModifiedAccessConditions + if_match, if_none_match = _get_match_headers(kwargs, 'match_condition', 'etag') + return ModifiedAccessConditions( + if_modified_since=kwargs.pop('if_modified_since', None), + if_unmodified_since=kwargs.pop('if_unmodified_since', None), + if_match=if_match or kwargs.pop('if_match', None), + if_none_match=if_none_match or kwargs.pop('if_none_match', None) + ) + + +def get_source_conditions(kwargs): + # type: (Dict[str, Any]) -> SourceModifiedAccessConditions + if_match, if_none_match = _get_match_headers(kwargs, 'source_match_condition', 'source_etag') + return SourceModifiedAccessConditions( + source_if_modified_since=kwargs.pop('source_if_modified_since', None), + source_if_unmodified_since=kwargs.pop('source_if_unmodified_since', None), + source_if_match=if_match or kwargs.pop('source_if_match', None), + source_if_none_match=if_none_match or kwargs.pop('source_if_none_match', None) + ) diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_client_async.py index 97aaef3e16f7..6318453ef1b0 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/blob_client_async.py @@ -15,7 +15,8 @@ from .._shared.base_client_async import AsyncStorageAccountHostsMixin from .._shared.policies_async import ExponentialRetry from .._shared.response_handlers import return_response_headers, process_storage_error -from .._deserialize import get_page_ranges_result, get_modify_conditions +from .._deserialize import get_page_ranges_result +from .._serialize import get_modify_conditions from .._generated.aio import AzureBlobStorage from .._generated.models import StorageErrorException, CpkInfo from .._deserialize import deserialize_blob_properties diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/container_client_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/container_client_async.py index c0288e68cdd8..3e87ddf8df9c 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/container_client_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/container_client_async.py @@ -27,7 +27,8 @@ from .._generated.models import ( StorageErrorException, SignedIdentifier) -from .._deserialize import deserialize_container_properties, get_modify_conditions +from .._deserialize import deserialize_container_properties +from .._serialize import get_modify_conditions from ..container_client import ContainerClient as ContainerClientBase from ..lease import get_access_conditions from ..models import ContainerProperties, BlobProperties, BlobType # pylint: disable=unused-import diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/lease_async.py b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/lease_async.py index a44b3e2f146e..21a27093f9ad 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/aio/lease_async.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/aio/lease_async.py @@ -15,7 +15,7 @@ from .._generated.models import ( StorageErrorException, LeaseAccessConditions) -from .._deserialize import get_modify_conditions +from .._serialize import get_modify_conditions from ..lease import LeaseClient as LeaseClientBase if TYPE_CHECKING: diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/blob_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/blob_client.py index 8aeb0c7c43f1..4494b05c343a 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/blob_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/blob_client.py @@ -37,13 +37,8 @@ StorageErrorException, UserDelegationKey, CpkInfo) - -from ._deserialize import ( - get_page_ranges_result, - get_modify_conditions, - get_source_conditions, - deserialize_blob_properties, - deserialize_blob_stream) +from ._serialize import get_modify_conditions, get_source_conditions +from ._deserialize import get_page_ranges_result, deserialize_blob_properties, deserialize_blob_stream from ._upload_helpers import ( upload_block_blob, upload_append_blob, diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/container_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/container_client.py index 99651c8566e3..57edb860f515 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/container_client.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/container_client.py @@ -33,7 +33,8 @@ from ._generated.models import ( StorageErrorException, SignedIdentifier) -from ._deserialize import deserialize_container_properties, get_modify_conditions +from ._deserialize import deserialize_container_properties +from ._serialize import get_modify_conditions from .models import ( # pylint: disable=unused-import ContainerProperties, BlobProperties, diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/lease.py b/sdk/storage/azure-storage-blob/azure/storage/blob/lease.py index 386050a1989c..200adab9d432 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/lease.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/lease.py @@ -15,7 +15,7 @@ from ._shared.response_handlers import return_response_headers, process_storage_error from ._generated.models import StorageErrorException, LeaseAccessConditions -from ._deserialize import get_modify_conditions +from ._serialize import get_modify_conditions if TYPE_CHECKING: from datetime import datetime diff --git a/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py b/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py index eceee4511f61..3559fbc2b783 100644 --- a/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py +++ b/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py @@ -367,6 +367,11 @@ def test_put_blob_with_if_match(self): # Assert self.assertIsNotNone(resp.get('etag')) + with self.assertRaises(ValueError): + blob.upload_blob(data, length=len(data), etag=etag) + with self.assertRaises(ValueError): + blob.upload_blob(data, length=len(data), match_condition=MatchConditions.IfNotModified) + @record def test_put_blob_with_if_match_fail(self): # Arrange @@ -398,6 +403,10 @@ def test_put_blob_with_if_none_match(self): # Assert self.assertIsNotNone(resp.get('etag')) + with self.assertRaises(ValueError): + blob.upload_blob(data, length=len(data), etag='0x111111111111111') + with self.assertRaises(ValueError): + blob.upload_blob(data, length=len(data), match_condition=MatchConditions.IfModified) @record def test_put_blob_with_if_none_match_fail(self): From 6763326fed476a99054fa9650b8c2cc8c64471a2 Mon Sep 17 00:00:00 2001 From: antisch Date: Fri, 18 Oct 2019 16:59:57 -0700 Subject: [PATCH 6/7] Updated release notes --- sdk/storage/azure-storage-blob/HISTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/storage/azure-storage-blob/HISTORY.md b/sdk/storage/azure-storage-blob/HISTORY.md index fa5e07d3928d..d028d107b657 100644 --- a/sdk/storage/azure-storage-blob/HISTORY.md +++ b/sdk/storage/azure-storage-blob/HISTORY.md @@ -9,6 +9,7 @@ - Removed types that were accidentally exposed from two modules. Only `BlobServiceClient`, `ContainerClient`, `BlobClient` and `LeaseClient` should be imported from azure.storage.blob.aio - `Logging` has been renamed to `BlobAnalyticsLogging`. +- All operations that take Etag conditional parameters (`if_match` and `if_none_match`) now take explicit `etag` and `match_condition` parameters, where `etag` is the Etag value, and `match_condition` is an instance of `azure.core.MatchConditions`. **New features** From 8bf3c423a94a5f914e3a7d02591733d01b4dac16 Mon Sep 17 00:00:00 2001 From: antisch Date: Fri, 18 Oct 2019 17:09:25 -0700 Subject: [PATCH 7/7] Revert skipped tests --- sdk/storage/azure-storage-blob/tests/test_page_blob.py | 3 --- sdk/storage/azure-storage-blob/tests/test_page_blob_async.py | 3 --- 2 files changed, 6 deletions(-) diff --git a/sdk/storage/azure-storage-blob/tests/test_page_blob.py b/sdk/storage/azure-storage-blob/tests/test_page_blob.py index 1e317828f49d..f268a9372aff 100644 --- a/sdk/storage/azure-storage-blob/tests/test_page_blob.py +++ b/sdk/storage/azure-storage-blob/tests/test_page_blob.py @@ -1382,7 +1382,6 @@ def test_incremental_copy_blob(self): @record def test_blob_tier_on_create(self): - pytest.skip("") url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() pbs = BlobServiceClient(url, credential=credential) @@ -1435,7 +1434,6 @@ def test_blob_tier_on_create(self): @record def test_blob_tier_set_tier_api(self): - pytest.skip("") url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() pbs = BlobServiceClient(url, credential=credential) @@ -1487,7 +1485,6 @@ def test_blob_tier_set_tier_api(self): @record def test_blob_tier_copy_blob(self): - pytest.skip("") url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() pbs = BlobServiceClient(url, credential=credential) diff --git a/sdk/storage/azure-storage-blob/tests/test_page_blob_async.py b/sdk/storage/azure-storage-blob/tests/test_page_blob_async.py index 1f3090897adf..c8a327fad3d8 100644 --- a/sdk/storage/azure-storage-blob/tests/test_page_blob_async.py +++ b/sdk/storage/azure-storage-blob/tests/test_page_blob_async.py @@ -1654,7 +1654,6 @@ def test_incremental_copy_blob(self): async def _test_blob_tier_on_create(self): # Test can only run live - pytest.skip("") if TestMode.need_recording_file(self.test_mode): return @@ -1716,7 +1715,6 @@ def test_blob_tier_on_create(self): loop.run_until_complete(self._test_blob_tier_on_create()) async def _test_blob_tier_set_tier_api(self): - pytest.skip("") await self._setup() url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential() @@ -1777,7 +1775,6 @@ def test_blob_tier_set_tier_api(self): loop.run_until_complete(self._test_blob_tier_set_tier_api()) async def _test_blob_tier_copy_blob(self): - pytest.skip("") await self._setup() url = self._get_premium_account_url() credential = self._get_premium_shared_key_credential()