1# pylint: disable=too-many-lines 2# ------------------------------------------------------------------------- 3# Copyright (c) Microsoft Corporation. All rights reserved. 4# Licensed under the MIT License. See License.txt in the project root for 5# license information. 6# -------------------------------------------------------------------------- 7 8from azure.core.paging import PageIterator, ItemPaged 9from azure.core.exceptions import HttpResponseError 10from ._deserialize import get_blob_properties_from_generated_code, parse_tags 11from ._generated.models import BlobItemInternal, BlobPrefix as GenBlobPrefix, FilterBlobItem 12from ._models import BlobProperties, FilteredBlob 13from ._shared.models import DictMixin 14from ._shared.response_handlers import return_context_and_deserialized, process_storage_error 15 16 17class BlobPropertiesPaged(PageIterator): 18 """An Iterable of Blob properties. 19 20 :ivar str service_endpoint: The service URL. 21 :ivar str prefix: A blob name prefix being used to filter the list. 22 :ivar str marker: The continuation token of the current page of results. 23 :ivar int results_per_page: The maximum number of results retrieved per API call. 24 :ivar str continuation_token: The continuation token to retrieve the next page of results. 25 :ivar str location_mode: The location mode being used to list results. The available 26 options include "primary" and "secondary". 27 :ivar current_page: The current page of listed results. 28 :vartype current_page: list(~azure.storage.blob.BlobProperties) 29 :ivar str container: The container that the blobs are listed from. 30 :ivar str delimiter: A delimiting character used for hierarchy listing. 31 32 :param callable command: Function to retrieve the next page of items. 33 :param str container: The name of the container. 34 :param str prefix: Filters the results to return only blobs whose names 35 begin with the specified prefix. 36 :param int results_per_page: The maximum number of blobs to retrieve per 37 call. 38 :param str continuation_token: An opaque continuation token. 39 :param str delimiter: 40 Used to capture blobs whose names begin with the same substring up to 41 the appearance of the delimiter character. The delimiter may be a single 42 character or a string. 43 :param location_mode: Specifies the location the request should be sent to. 44 This mode only applies for RA-GRS accounts which allow secondary read access. 45 Options include 'primary' or 'secondary'. 46 """ 47 def __init__( 48 self, command, 49 container=None, 50 prefix=None, 51 results_per_page=None, 52 continuation_token=None, 53 delimiter=None, 54 location_mode=None): 55 super(BlobPropertiesPaged, self).__init__( 56 get_next=self._get_next_cb, 57 extract_data=self._extract_data_cb, 58 continuation_token=continuation_token or "" 59 ) 60 self._command = command 61 self.service_endpoint = None 62 self.prefix = prefix 63 self.marker = None 64 self.results_per_page = results_per_page 65 self.container = container 66 self.delimiter = delimiter 67 self.current_page = None 68 self.location_mode = location_mode 69 70 def _get_next_cb(self, continuation_token): 71 try: 72 return self._command( 73 prefix=self.prefix, 74 marker=continuation_token or None, 75 maxresults=self.results_per_page, 76 cls=return_context_and_deserialized, 77 use_location=self.location_mode) 78 except HttpResponseError as error: 79 process_storage_error(error) 80 81 def _extract_data_cb(self, get_next_return): 82 self.location_mode, self._response = get_next_return 83 self.service_endpoint = self._response.service_endpoint 84 self.prefix = self._response.prefix 85 self.marker = self._response.marker 86 self.results_per_page = self._response.max_results 87 self.container = self._response.container_name 88 self.current_page = [self._build_item(item) for item in self._response.segment.blob_items] 89 90 return self._response.next_marker or None, self.current_page 91 92 def _build_item(self, item): 93 if isinstance(item, BlobProperties): 94 return item 95 if isinstance(item, BlobItemInternal): 96 blob = get_blob_properties_from_generated_code(item) # pylint: disable=protected-access 97 blob.container = self.container 98 return blob 99 return item 100 101 102class BlobPrefixPaged(BlobPropertiesPaged): 103 def __init__(self, *args, **kwargs): 104 super(BlobPrefixPaged, self).__init__(*args, **kwargs) 105 self.name = self.prefix 106 107 def _extract_data_cb(self, get_next_return): 108 continuation_token, _ = super(BlobPrefixPaged, self)._extract_data_cb(get_next_return) 109 self.current_page = self._response.segment.blob_prefixes + self._response.segment.blob_items 110 self.current_page = [self._build_item(item) for item in self.current_page] 111 self.delimiter = self._response.delimiter 112 113 return continuation_token, self.current_page 114 115 def _build_item(self, item): 116 item = super(BlobPrefixPaged, self)._build_item(item) 117 if isinstance(item, GenBlobPrefix): 118 return BlobPrefix( 119 self._command, 120 container=self.container, 121 prefix=item.name, 122 results_per_page=self.results_per_page, 123 location_mode=self.location_mode) 124 return item 125 126 127class BlobPrefix(ItemPaged, DictMixin): 128 """An Iterable of Blob properties. 129 130 Returned from walk_blobs when a delimiter is used. 131 Can be thought of as a virtual blob directory. 132 133 :ivar str name: The prefix, or "directory name" of the blob. 134 :ivar str service_endpoint: The service URL. 135 :ivar str prefix: A blob name prefix being used to filter the list. 136 :ivar str marker: The continuation token of the current page of results. 137 :ivar int results_per_page: The maximum number of results retrieved per API call. 138 :ivar str next_marker: The continuation token to retrieve the next page of results. 139 :ivar str location_mode: The location mode being used to list results. The available 140 options include "primary" and "secondary". 141 :ivar current_page: The current page of listed results. 142 :vartype current_page: list(~azure.storage.blob.BlobProperties) 143 :ivar str container: The container that the blobs are listed from. 144 :ivar str delimiter: A delimiting character used for hierarchy listing. 145 146 :param callable command: Function to retrieve the next page of items. 147 :param str prefix: Filters the results to return only blobs whose names 148 begin with the specified prefix. 149 :param int results_per_page: The maximum number of blobs to retrieve per 150 call. 151 :param str marker: An opaque continuation token. 152 :param str delimiter: 153 Used to capture blobs whose names begin with the same substring up to 154 the appearance of the delimiter character. The delimiter may be a single 155 character or a string. 156 :param location_mode: Specifies the location the request should be sent to. 157 This mode only applies for RA-GRS accounts which allow secondary read access. 158 Options include 'primary' or 'secondary'. 159 """ 160 def __init__(self, *args, **kwargs): 161 super(BlobPrefix, self).__init__(*args, page_iterator_class=BlobPrefixPaged, **kwargs) 162 self.name = kwargs.get('prefix') 163 self.prefix = kwargs.get('prefix') 164 self.results_per_page = kwargs.get('results_per_page') 165 self.container = kwargs.get('container') 166 self.delimiter = kwargs.get('delimiter') 167 self.location_mode = kwargs.get('location_mode') 168 169 170class FilteredBlobPaged(PageIterator): 171 """An Iterable of Blob properties. 172 173 :ivar str service_endpoint: The service URL. 174 :ivar str prefix: A blob name prefix being used to filter the list. 175 :ivar str marker: The continuation token of the current page of results. 176 :ivar int results_per_page: The maximum number of results retrieved per API call. 177 :ivar str continuation_token: The continuation token to retrieve the next page of results. 178 :ivar str location_mode: The location mode being used to list results. The available 179 options include "primary" and "secondary". 180 :ivar current_page: The current page of listed results. 181 :vartype current_page: list(~azure.storage.blob.FilteredBlob) 182 :ivar str container: The container that the blobs are listed from. 183 184 :param callable command: Function to retrieve the next page of items. 185 :param str container: The name of the container. 186 :param int results_per_page: The maximum number of blobs to retrieve per 187 call. 188 :param str continuation_token: An opaque continuation token. 189 :param location_mode: Specifies the location the request should be sent to. 190 This mode only applies for RA-GRS accounts which allow secondary read access. 191 Options include 'primary' or 'secondary'. 192 """ 193 def __init__( 194 self, command, 195 container=None, 196 results_per_page=None, 197 continuation_token=None, 198 location_mode=None): 199 super(FilteredBlobPaged, self).__init__( 200 get_next=self._get_next_cb, 201 extract_data=self._extract_data_cb, 202 continuation_token=continuation_token or "" 203 ) 204 self._command = command 205 self.service_endpoint = None 206 self.marker = continuation_token 207 self.results_per_page = results_per_page 208 self.container = container 209 self.current_page = None 210 self.location_mode = location_mode 211 212 def _get_next_cb(self, continuation_token): 213 try: 214 return self._command( 215 marker=continuation_token or None, 216 maxresults=self.results_per_page, 217 cls=return_context_and_deserialized, 218 use_location=self.location_mode) 219 except HttpResponseError as error: 220 process_storage_error(error) 221 222 def _extract_data_cb(self, get_next_return): 223 self.location_mode, self._response = get_next_return 224 self.service_endpoint = self._response.service_endpoint 225 self.marker = self._response.next_marker 226 self.current_page = [self._build_item(item) for item in self._response.blobs] 227 228 return self._response.next_marker or None, self.current_page 229 230 @staticmethod 231 def _build_item(item): 232 if isinstance(item, FilterBlobItem): 233 tags = parse_tags(item.tags) 234 blob = FilteredBlob(name=item.name, container_name=item.container_name, tags=tags) 235 return blob 236 return item 237