Search code examples
pythonmicrosoft-graph-apimicrosoft-graph-sdks

How to iterate through paginated results in the Python SDK for Microsoft Graph?


I'm getting to grips with the Python SDK, having never used GraphQL before (but I'm familiar with the basic concept). I'm able to retrieve the odata_next_link value from responses, but I'm not sure how to use it. I note from here that:

You should include the entire URL in the @odata.nextLink property in your request for the next page of results. Depending on the API that the query is being performed against, the @odata.nextLink URL value will contain either a $skiptoken or a $skip query parameter. The URL also contains all the other query parameters present in the original request. Do not try to extract the $skiptoken or $skip value and use it in a different request.

However, I'm not sure how to include that URL in the next request. Currently, my queries look like response = await graph_client.groups.by_group_id(group_id).transitive_members.get() - I don't see an option there to change the base url. I thought I could do something like:

query_params = GroupsRequestBuilder.GroupsRequestBuilderGetQueryParameters(
  skip_token = parse_qs(urlparse(response.odata_next_link).query)['$skipToken'][0]
)
request_configuration = GroupsRequestBuilder.GroupsRequestBuilderGetRequestConfiguration(
  query_parameters=query_params
)
response = await graph_client.[...].get(request_configuration)

but that reports GroupsRequestBuilder.GroupsRequestBuilderGetQueryParameters.__init__() got an unexpected keyword argument 'skip_token' (and similarly for if I try naming the parameter skiptoken or skipToken)

Frustratingly, there's no code example here - but, based on those examples, I did search the repo for an Iterator - with no results.


Solution

  • We do not have a page iterator for the Python SDK yet, however there is added support for using a raw url for the request. In the case of pagination, a user can use the odata_next_link property value to make a fresh request using with_url and get items in the next page.

    Here's a working example:

    
    from msgraph.generated.users.users_request_builder import UsersRequestBuilder
    
    async def get_users():
    
        query_params = UsersRequestBuilder.UsersRequestBuilderGetQueryParameters(
    
        select=["id", "displayName", "createdDateTime"],
    
        top=5,
    
        )
    
        request_config = UsersRequestBuilder.UsersRequestBuilderGetRequestConfiguration(
    
            query_parameters=query_params
    
        )
    
        users_list = []
    
        users = await client.users.get(request_configuration=request_config)
    
        for user in users.value:
    
            users_list.append(user)
    
        next_link = users.odata_next_link
    
        while next_link:
    
            users = await client.users.with_url(next_link).get()
    
            next_link = users.odata_next_link
    
            for user in users.value:
    
                users_list.append(user)
    
        print(len(users_list))