oracle / oci-python-sdk

Oracle Cloud Infrastructure SDK for Python
https://cloud.oracle.com/cloud-infrastructure
Other
387 stars 280 forks source link

Pagination does not work for `identity_domains_client.list_groups` if attributes are added #708

Open farisdurrani opened 2 weeks ago

farisdurrani commented 2 weeks ago

The below code attempts to list all groups in an identity domain. However, adding either attribute_sets or attributes will cause the response to indicate has_next_page == True and next_page to have a value even if the results are already complete.

import oci

config = oci.config.from_file("~/.oci/config", "DEFAULT")
tenancy_ocid = config["tenancy"]

# Get the domain endpoint
identity_client = oci.identity.IdentityClient(config)
list_domains_response = identity_client.list_domains(tenancy_ocid)
domain01_endpoint = list_domains_response.data[0].url

# Get the groups
identity_domains_client = oci.identity_domains.IdentityDomainsClient(
    config, domain01_endpoint
)
list_groups_response = identity_domains_client.list_groups(
    # BUG: adding attribute_sets or attributes causes the `has_next_page` to be true
    attribute_sets=["request"],
    attributes="members,ocid",
)
print(list_groups_response.has_next_page)
# outputs True even if the response is already complete and no more pages are expected

Versions

adizohar commented 2 weeks ago

Here a workaround to fix it: This is part of a class, without class remove the self.

##########################################################################
    # Pagination main call
    ##########################################################################
    def __list_call_get_all_results(self, list_func_ref, *list_func_args, **list_func_kwargs):

        aggregated_results = []
        for call_result in self.__list_call_get_all_results_generator_domains(list_func_ref, *list_func_args, **list_func_kwargs):
            aggregated_results.extend(call_result.data.resources)
            final_response = oci.Response(call_result.status, call_result.headers, aggregated_results, call_result.request)
        return final_response

    ##########################################################################
    # Pagination result generator
    ##########################################################################
    def __list_call_get_all_results_generator_domains(self, list_func_ref, *list_func_args, **list_func_kwargs):

        keep_paginating = True

        while keep_paginating:
            call_result = oci.retry.DEFAULT_RETRY_STRATEGY.make_retrying_call(list_func_ref, *list_func_args, **list_func_kwargs)
            yield call_result

            start_index = call_result.data.start_index
            total_results = call_result.data.total_results
            items_per_page = call_result.data.items_per_page
            next_index = start_index + items_per_page

            # print("\nCalled " + str(list_func_ref))
            # print("start_index: " + str(start_index) + ", " + "total_results: " + str(total_results) + ", " + "items_per_page: " + str(items_per_page) + ", " + "next_index: " + str(next_index))

            if next_index < total_results:
                list_func_kwargs['start_index'] = next_index
            else:
                keep_paginating = False