1# coding: utf-8 2# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. 3# This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license. 4 5from .. import dns, object_storage 6from .. import retry 7from ..response import Response 8 9 10def list_call_get_up_to_limit(list_func_ref, record_limit, page_size, *list_func_args, **list_func_kwargs): 11 """ 12 Calls a list operation and automatically fetches more data from the service (automatically following pagination tokens) until 13 the desired number of records is reached (or there are no more records left, if the total number of records is less than 14 the desired number of records). Apart from the formally listed parameters for this function, any additional 15 positional (``*list_func_args``) and keyword (``**list_func_kwargs``) arguments will be passed to the list operation. 16 17 Results are eagerly loaded and the response returned by this function will contain all the data up to the desired 18 number of records (or there are no more records left, whichever is first). If you wish to lazy load results, then use 19 the version of this method which produces a generator: :py:func:`~oci.pagination.list_call_get_up_to_limit_generator` 20 21 :param function list_func_ref: 22 A reference to the list operation which we will call 23 24 :param int record_limit: 25 The maximum number of records to fetch. We may fetch less records than this if the total number of records is less than 26 this value. If a record_limit is not provided then we will only fetch a single page of data 27 28 :param int page_size: 29 The number of records to retrieve per list operation call 30 31 :return: 32 A :class:`~oci.response.Response` whose data attribute contains all the records we retrieved. The other attributes of the 33 :class:`~oci.response.Response` object will be sourced from the last response we received from calling the list operation on the service. 34 :rtype: :class:`~oci.response.Response` 35 """ 36 call_result = None 37 aggregated_results = [] 38 is_dns_record_collection = False 39 dns_record_collection_class = None 40 is_list_objects_response = False 41 list_objects_prefixes = set() 42 for response in list_call_get_up_to_limit_generator(list_func_ref, record_limit, page_size, 'response', *list_func_args, **list_func_kwargs): 43 call_result = response 44 45 if isinstance(call_result.data, dns.models.RecordCollection) or isinstance(call_result.data, dns.models.RRSet): 46 is_dns_record_collection = True 47 dns_record_collection_class = call_result.data.__class__ 48 aggregated_results.extend(call_result.data.items) 49 elif isinstance(call_result.data, object_storage.models.ListObjects): 50 is_list_objects_response = True 51 aggregated_results.extend(call_result.data.objects) 52 if call_result.data.prefixes: 53 list_objects_prefixes.update(call_result.data.prefixes) 54 else: 55 aggregated_results.extend(call_result.data) if isinstance(call_result.data, list) \ 56 else aggregated_results.extend(call_result.data.items) 57 58 if is_dns_record_collection: 59 final_response = Response( 60 call_result.status, 61 call_result.headers, 62 dns_record_collection_class(items=aggregated_results), 63 call_result.request 64 ) 65 elif is_list_objects_response: 66 final_response = Response( 67 call_result.status, 68 call_result.headers, 69 object_storage.models.ListObjects( 70 objects=aggregated_results, 71 prefixes=list(list_objects_prefixes) 72 ), 73 call_result.request 74 ) 75 else: 76 final_response = Response(call_result.status, call_result.headers, aggregated_results, call_result.request) 77 return final_response 78 79 80def list_call_get_up_to_limit_generator(list_func_ref, record_limit, page_size, yield_mode, *list_func_args, **list_func_kwargs): 81 """ 82 Calls a list operation and automatically fetches more data from the service (automatically following pagination tokens) until 83 the desired number of records is reached (or there are no more records left, if the total number of records is less than 84 the desired number of records). Apart from the formally listed parameters for this function, any additional 85 positional (``*list_func_args``) and keyword (``**list_func_kwargs``) arguments will be passed to the list operation. 86 87 This function produces a generator and lazily loads results. That is, service calls will only be made to fetch more data 88 when needed as we iterate through results produced by the generator; this contrasts with the eagarily loaded 89 :py:func:`~oci.pagination.list_call_get_up_to_limit` function, which makes all the required service calls when it is called. 90 91 The generator also supports vending two types of objects - either the raw responses received from calling the list operation, 92 or the individual model objects which are contained within the response's ``data`` attribute (which should be 93 a list of model objects). 94 95 :param function list_func_ref: 96 A reference to the list operation which we will call 97 98 :param int record_limit: 99 The maximum number of records to fetch. We may fetch less records than this if the total number of records is less than 100 this value. If a record_limit is not provided then we will only fetch a single page of data 101 102 :param int page_size: 103 The number of records to retrieve per list operation call 104 105 :param str yield_mode: 106 Either ``response`` or ``record``. This will control whether the generator returned by this function yields 107 either :class:`~oci.response.Response` objects (if the value is ``response``), or whether it yields the 108 individual model objects which are contained within the response's ``data`` attribute (which should 109 be a list of model objects) 110 111 :return: 112 A generator that, depending on the ``yield_mode``, will yield either :class:`~oci.response.Response` objects 113 or the individual model objects which are contained within the response's ``data`` attribute (which should 114 be a list of model objects) 115 """ 116 if not record_limit and not page_size: 117 raise ValueError('You must provide one, or both, of a record_limit and page_size') 118 119 # If no limit was provided, make a single call 120 if record_limit is None: 121 list_func_kwargs['limit'] = page_size 122 single_call_result = retry.DEFAULT_RETRY_STRATEGY.make_retrying_call(list_func_ref, *list_func_args, **list_func_kwargs) 123 124 if yield_mode == 'response': 125 yield single_call_result 126 else: 127 items_to_yield = [] 128 if isinstance(single_call_result.data, dns.models.RecordCollection) or isinstance(single_call_result.data, dns.models.RRSet): 129 items_to_yield = single_call_result.data.items 130 elif isinstance(single_call_result.data, object_storage.models.ListObjects): 131 items_to_yield = single_call_result.data.objects 132 else: 133 items_to_yield = single_call_result.data 134 135 for item in items_to_yield: 136 yield item 137 138 return # This will terminate after we yield everything we can from the single result 139 140 # If we have a limit, make calls until we get that amount of data 141 keep_paginating = True 142 remaining_items_to_fetch = record_limit 143 call_result = None 144 while keep_paginating and remaining_items_to_fetch > 0: 145 list_func_kwargs['limit'] = min(page_size, remaining_items_to_fetch) 146 147 call_result = retry.DEFAULT_RETRY_STRATEGY.make_retrying_call(list_func_ref, *list_func_args, **list_func_kwargs) 148 if yield_mode == 'response': 149 yield call_result 150 else: 151 items_to_yield = [] 152 if isinstance(call_result.data, dns.models.RecordCollection) or isinstance(call_result.data, dns.models.RRSet): 153 items_to_yield = call_result.data.items 154 elif isinstance(call_result.data, object_storage.models.ListObjects): 155 items_to_yield = call_result.data.objects 156 else: 157 items_to_yield = call_result.data if isinstance(call_result.data, list) else call_result.data.items 158 159 for item in items_to_yield: 160 yield item 161 162 if isinstance(call_result.data, dns.models.RecordCollection) or isinstance(call_result.data, dns.models.RRSet): 163 remaining_items_to_fetch -= len(call_result.data.items) 164 elif isinstance(call_result.data, object_storage.models.ListObjects): 165 remaining_items_to_fetch -= len(call_result.data.objects) 166 else: 167 remaining_items_to_fetch -= len(call_result.data) if isinstance(call_result.data, list) else len(call_result.data.items) 168 169 if isinstance(call_result.data, object_storage.models.ListObjects): 170 if call_result.data.next_start_with is not None: 171 list_func_kwargs['start'] = call_result.data.next_start_with 172 keep_paginating = (call_result.data.next_start_with is not None) 173 else: 174 if call_result.next_page is not None: 175 list_func_kwargs['page'] = call_result.next_page 176 177 keep_paginating = call_result.has_next_page 178 179 180def list_call_get_all_results(list_func_ref, *list_func_args, **list_func_kwargs): 181 """ 182 Calls a list operation and automatically fetches more data from the service (automatically following pagination tokens) until 183 the no more records are available. Apart from the formally listed parameters for this function, any additional 184 positional (``*list_func_args``) and keyword (``**list_func_kwargs``) arguments will be passed to the list operation. 185 186 Results are eagerly loaded and the response returned by this function will contain all the available data. If you wish 187 to lazy load results, then use the version of this method which produces a generator: 188 :py:func:`~oci.pagination.list_call_get_all_results_generator` 189 190 :param function list_func_ref: 191 A reference to the list operation which we will call 192 193 :return: 194 A :class:`~oci.response.Response` whose data attribute contains all the records we retrieved. The other attributes of the 195 :class:`~oci.response.Response` object will be sourced from the last response we received from calling the list operation on the service. 196 :rtype: :class:`~oci.response.Response` 197 """ 198 199 aggregated_results = [] 200 call_result = None 201 is_dns_record_collection = False 202 dns_record_collection_class = None 203 is_list_objects_response = False 204 list_objects_prefixes = set() 205 for response in list_call_get_all_results_generator(list_func_ref, 'response', *list_func_args, **list_func_kwargs): 206 call_result = response 207 if isinstance(call_result.data, dns.models.RecordCollection) or isinstance(call_result.data, dns.models.RRSet): 208 is_dns_record_collection = True 209 dns_record_collection_class = call_result.data.__class__ 210 aggregated_results.extend(call_result.data.items) 211 elif isinstance(call_result.data, object_storage.models.ListObjects): 212 is_list_objects_response = True 213 aggregated_results.extend(call_result.data.objects) 214 if call_result.data.prefixes: 215 list_objects_prefixes.update(call_result.data.prefixes) 216 else: 217 aggregated_results.extend(call_result.data) if isinstance(call_result.data, list) \ 218 else aggregated_results.extend(call_result.data.items) 219 220 if is_dns_record_collection: 221 final_response = Response( 222 call_result.status, 223 call_result.headers, 224 dns_record_collection_class(items=aggregated_results), 225 call_result.request 226 ) 227 elif is_list_objects_response: 228 final_response = Response( 229 call_result.status, 230 call_result.headers, 231 object_storage.models.ListObjects( 232 objects=aggregated_results, 233 prefixes=list(list_objects_prefixes) 234 ), 235 call_result.request 236 ) 237 else: 238 final_response = Response(call_result.status, call_result.headers, aggregated_results, call_result.request) 239 return final_response 240 241 242def list_call_get_all_results_generator(list_func_ref, yield_mode, *list_func_args, **list_func_kwargs): 243 """ 244 Calls a list operation and automatically fetches more data from the service (automatically following pagination tokens) until 245 the no more records are available. Apart from the formally listed parameters for this function, any additional 246 positional (``*list_func_args``) and keyword (``**list_func_kwargs``) arguments will be passed to the list operation. 247 248 This function produces a generator and lazily loads results. That is, service calls will only be made to fetch more data 249 when needed as we iterate through results produced by the generator; this contrasts with the eagarily loaded 250 :py:func:`~oci.pagination.list_call_get_all_results` function, which makes all the required service calls when it is called. 251 252 The generator also supports vending two types of objects - either the raw responses received from calling the list operation, 253 or the individual model objects which are contained within the response's ``data`` attribute (which should be 254 a list of model objects). 255 256 :param function list_func_ref: 257 A reference to the list operation which we will call 258 259 :param str yield_mode: 260 Either ``response`` or ``record``. This will control whether the generator returned by this function yields 261 either :class:`~oci.response.Response` objects (if the value is ``response``), or whether it yields the 262 individual model objects which are contained within the response's ``data`` attribute (which should 263 be a list of model objects) 264 265 :return: 266 A generator that, depending on the ``yield_mode``, will yield either :class:`~oci.response.Response` objects 267 or the individual model objects which are contained within the response's ``data`` attribute (which should 268 be a list of model objects) 269 """ 270 keep_paginating = True 271 call_result = None 272 273 while keep_paginating: 274 call_result = retry.DEFAULT_RETRY_STRATEGY.make_retrying_call(list_func_ref, *list_func_args, **list_func_kwargs) 275 if yield_mode == 'response': 276 yield call_result 277 else: 278 items_to_yield = [] 279 if isinstance(call_result.data, dns.models.RecordCollection) or isinstance(call_result.data, dns.models.RRSet): 280 items_to_yield = call_result.data.items 281 elif isinstance(call_result.data, object_storage.models.ListObjects): 282 items_to_yield = call_result.data.objects 283 else: 284 items_to_yield = call_result.data 285 286 for item in items_to_yield: 287 yield item 288 289 if isinstance(call_result.data, object_storage.models.ListObjects): 290 if call_result.data.next_start_with is not None: 291 list_func_kwargs['start'] = call_result.data.next_start_with 292 keep_paginating = (call_result.data.next_start_with is not None) 293 else: 294 if call_result.next_page is not None: 295 list_func_kwargs['page'] = call_result.next_page 296 297 keep_paginating = call_result.has_next_page 298