6363 _parse_lease ,
6464 _convert_xml_to_signed_identifiers_and_access ,
6565 _parse_base_properties ,
66+ _parse_account_information ,
6667)
6768from ._download_chunking import _download_blob_chunks
6869from ._error import (
8586 __version__ as package_version ,
8687)
8788
89+ _CONTAINER_ALREADY_EXISTS_ERROR_CODE = 'ContainerAlreadyExists'
90+ _BLOB_NOT_FOUND_ERROR_CODE = 'BlobNotFound'
91+ _CONTAINER_NOT_FOUND_ERROR_CODE = 'ContainerNotFound'
92+
8893if sys .version_info >= (3 ,):
8994 from io import BytesIO
9095else :
@@ -622,7 +627,7 @@ def create_container(self, container_name, metadata=None,
622627
623628 if not fail_on_exist :
624629 try :
625- self ._perform_request (request )
630+ self ._perform_request (request , expected_errors = [ _CONTAINER_ALREADY_EXISTS_ERROR_CODE ] )
626631 return True
627632 except AzureHttpError as ex :
628633 _dont_fail_on_exist (ex )
@@ -873,7 +878,7 @@ def delete_container(self, container_name, fail_not_exist=False,
873878
874879 if not fail_not_exist :
875880 try :
876- self ._perform_request (request )
881+ self ._perform_request (request , expected_errors = [ _CONTAINER_NOT_FOUND_ERROR_CODE ] )
877882 return True
878883 except AzureHttpError as ex :
879884 _dont_fail_not_exist (ex )
@@ -1316,6 +1321,33 @@ def _list_blobs(self, container_name, prefix=None, marker=None,
13161321
13171322 return self ._perform_request (request , _convert_xml_to_blob_list , operation_context = _context )
13181323
1324+ def get_blob_account_information (self , container_name = None , blob_name = None , timeout = None ):
1325+ """
1326+ Gets information related to the storage account.
1327+ The information can also be retrieved if the user has a SAS to a container or blob.
1328+
1329+ :param str container_name:
1330+ Name of existing container.
1331+ Optional, unless using a SAS token to a specific container or blob, in which case it's required.
1332+ :param str blob_name:
1333+ Name of existing blob.
1334+ Optional, unless using a SAS token to a specific blob, in which case it's required.
1335+ :param int timeout:
1336+ The timeout parameter is expressed in seconds.
1337+ :return: The :class:`~azure.storage.blob.models.AccountInformation`.
1338+ """
1339+ request = HTTPRequest ()
1340+ request .method = 'HEAD'
1341+ request .host_locations = self ._get_host_locations (secondary = True )
1342+ request .path = _get_path (container_name , blob_name )
1343+ request .query = {
1344+ 'restype' : 'account' ,
1345+ 'comp' : 'properties' ,
1346+ 'timeout' : _int_to_str (timeout ),
1347+ }
1348+
1349+ return self ._perform_request (request , _parse_account_information )
1350+
13191351 def get_blob_service_stats (self , timeout = None ):
13201352 '''
13211353 Retrieves statistics related to replication for the Blob service. It is
@@ -1354,7 +1386,7 @@ def get_blob_service_stats(self, timeout=None):
13541386
13551387 def set_blob_service_properties (
13561388 self , logging = None , hour_metrics = None , minute_metrics = None ,
1357- cors = None , target_version = None , timeout = None , delete_retention_policy = None ):
1389+ cors = None , target_version = None , timeout = None , delete_retention_policy = None , static_website = None ):
13581390 '''
13591391 Sets the properties of a storage account's Blob service, including
13601392 Azure Storage Analytics. If an element (ex Logging) is left as None, the
@@ -1389,6 +1421,11 @@ def set_blob_service_properties(
13891421 It also specifies the number of days and versions of blob to keep.
13901422 :type delete_retention_policy:
13911423 :class:`~azure.storage.common.models.DeleteRetentionPolicy`
1424+ :param static_website:
1425+ Specifies whether the static website feature is enabled,
1426+ and if yes, indicates the index document and 404 error document to use.
1427+ :type static_website:
1428+ :class:`~azure.storage.common.models.StaticWebsite`
13921429 '''
13931430 request = HTTPRequest ()
13941431 request .method = 'PUT'
@@ -1401,7 +1438,7 @@ def set_blob_service_properties(
14011438 }
14021439 request .body = _get_request_body (
14031440 _convert_service_properties_to_xml (logging , hour_metrics , minute_metrics ,
1404- cors , target_version , delete_retention_policy ))
1441+ cors , target_version , delete_retention_policy , static_website ))
14051442
14061443 self ._perform_request (request )
14071444
@@ -1575,10 +1612,21 @@ def exists(self, container_name, blob_name=None, snapshot=None, timeout=None):
15751612 '''
15761613 _validate_not_none ('container_name' , container_name )
15771614 try :
1578- if blob_name is None :
1579- self .get_container_properties (container_name , timeout = timeout )
1580- else :
1581- self .get_blob_properties (container_name , blob_name , snapshot = snapshot , timeout = timeout )
1615+ # make head request to see if container/blob/snapshot exists
1616+ request = HTTPRequest ()
1617+ request .method = 'GET' if blob_name is None else 'HEAD'
1618+ request .host_locations = self ._get_host_locations (secondary = True )
1619+ request .path = _get_path (container_name , blob_name )
1620+ request .query = {
1621+ 'snapshot' : _to_str (snapshot ),
1622+ 'timeout' : _int_to_str (timeout ),
1623+ 'restype' : 'container' if blob_name is None else None ,
1624+ }
1625+
1626+ expected_errors = [_CONTAINER_NOT_FOUND_ERROR_CODE ] if blob_name is None \
1627+ else [_CONTAINER_NOT_FOUND_ERROR_CODE , _BLOB_NOT_FOUND_ERROR_CODE ]
1628+ self ._perform_request (request , expected_errors = expected_errors )
1629+
15821630 return True
15831631 except AzureHttpError as ex :
15841632 _dont_fail_not_exist (ex )
0 commit comments