diff --git a/src/sempy_labs/_helper_functions.py b/src/sempy_labs/_helper_functions.py index d5bcdb9c..8aaee87d 100644 --- a/src/sempy_labs/_helper_functions.py +++ b/src/sempy_labs/_helper_functions.py @@ -1619,6 +1619,27 @@ def pagination(client, response): return responses +def graph_pagination(response, headers): + + responses = [] + response_json = response.json() + responses.append(response_json) + + # Check for pagination + odata_next_link = response_json.get("@odata.nextLink") + + # Loop to handle pagination + while odata_next_link is not None: + response = requests.get(odata_next_link, headers=headers) + response_json = response.json() + responses.append(response_json) + + # Update the odata next link for the next iteration + odata_next_link = response_json.get("@odata.nextLink") + + return responses + + def resolve_deployment_pipeline_id(deployment_pipeline: str | UUID) -> UUID: """ Obtains the Id for a given deployment pipeline. @@ -2254,7 +2275,10 @@ def get_token(self, *scopes, **kwargs) -> AccessToken: if response.status_code not in status_codes: raise FabricHTTPException(response) if uses_pagination: - responses = pagination(c, response) + if client == "graph": + responses = graph_pagination(response, headers) + else: + responses = pagination(c, response) return responses else: return response diff --git a/src/sempy_labs/graph/_groups.py b/src/sempy_labs/graph/_groups.py index 779712ad..61f05714 100644 --- a/src/sempy_labs/graph/_groups.py +++ b/src/sempy_labs/graph/_groups.py @@ -55,7 +55,7 @@ def list_groups() -> pd.DataFrame: A pandas dataframe showing a list of groups and their properties. """ - result = _base_api(request="groups", client="graph").json() + result = _base_api(request="groups", client="graph", uses_pagination=True) columns = { "Group Id": "string", @@ -76,24 +76,25 @@ def list_groups() -> pd.DataFrame: df = _create_dataframe(columns=columns) rows = [] - for v in result.get("value"): - rows.append( - { - "Group Id": v.get("id"), - "Group Name": v.get("displayName"), - "Mail": v.get("mail"), - "Description": v.get("description"), - "Classification": v.get("classification"), - "Mail Enabled": v.get("mailEnabled"), - "Security Enabled": v.get("securityEnabled"), - "Created Date Time": v.get("createdDateTime"), - "Expiration Date Time": v.get("expirationDateTime"), - "Renewed Date Time": v.get("renewedDateTime"), - "Deleted Date Time": v.get("deletedDateTime"), - "Visibility": v.get("visibility"), - "Security Identifier": v.get("securityIdentifier"), - } - ) + for r in result: + for v in r.get("value", []): + rows.append( + { + "Group Id": v.get("id"), + "Group Name": v.get("displayName"), + "Mail": v.get("mail"), + "Description": v.get("description"), + "Classification": v.get("classification"), + "Mail Enabled": v.get("mailEnabled"), + "Security Enabled": v.get("securityEnabled"), + "Created Date Time": v.get("createdDateTime"), + "Expiration Date Time": v.get("expirationDateTime"), + "Renewed Date Time": v.get("renewedDateTime"), + "Deleted Date Time": v.get("deletedDateTime"), + "Visibility": v.get("visibility"), + "Security Identifier": v.get("securityIdentifier"), + } + ) if rows: df = pd.DataFrame(rows, columns=list(columns.keys())) @@ -190,7 +191,9 @@ def list_group_members(group: str | UUID) -> pd.DataFrame: group_id = resolve_group_id(group) - result = _base_api(request=f"groups/{group_id}/members", client="graph").json() + result = _base_api( + request=f"groups/{group_id}/members", client="graph", uses_pagination=True + ) columns = { "Member Id": "string", @@ -209,22 +212,23 @@ def list_group_members(group: str | UUID) -> pd.DataFrame: df = _create_dataframe(columns=columns) rows = [] - for v in result.get("value"): - rows.append( - { - "Member Id": v.get("id"), - "Member Name": v.get("displayName"), - "User Principal Name": v.get("userPrincipalName"), - "Mail": v.get("mail"), - "Job Title": v.get("jobTitle"), - "Office Location": v.get("officeLocation"), - "Mobile Phone": v.get("mobilePhone"), - "Business Phones": str(v.get("businessPhones")), - "Preferred Language": v.get("preferredLanguage"), - "Given Name": v.get("givenName"), - "Surname": v.get("surname"), - } - ) + for r in result: + for v in r.get("value", []): + rows.append( + { + "Member Id": v.get("id"), + "Member Name": v.get("displayName"), + "User Principal Name": v.get("userPrincipalName"), + "Mail": v.get("mail"), + "Job Title": v.get("jobTitle"), + "Office Location": v.get("officeLocation"), + "Mobile Phone": v.get("mobilePhone"), + "Business Phones": str(v.get("businessPhones")), + "Preferred Language": v.get("preferredLanguage"), + "Given Name": v.get("givenName"), + "Surname": v.get("surname"), + } + ) if rows: df = pd.DataFrame(rows, columns=list(columns.keys())) @@ -254,7 +258,9 @@ def list_group_owners(group: str | UUID) -> pd.DataFrame: group_id = resolve_group_id(group) - result = _base_api(request=f"groups/{group_id}/owners", client="graph").json() + result = _base_api( + request=f"groups/{group_id}/owners", client="graph", uses_pagination=True + ) columns = { "Owner Id": "string", @@ -273,22 +279,23 @@ def list_group_owners(group: str | UUID) -> pd.DataFrame: df = _create_dataframe(columns=columns) rows = [] - for v in result.get("value"): - rows.append( - { - "Owner Id": v.get("id"), - "Owner Name": v.get("displayName"), - "User Principal Name": v.get("userPrincipalName"), - "Mail": v.get("mail"), - "Job Title": v.get("jobTitle"), - "Office Location": v.get("officeLocation"), - "Mobile Phone": v.get("mobilePhone"), - "Business Phones": str(v.get("businessPhones")), - "Preferred Language": v.get("preferredLanguage"), - "Given Name": v.get("givenName"), - "Surname": v.get("surname"), - } - ) + for r in result: + for v in r.get("value", []): + rows.append( + { + "Owner Id": v.get("id"), + "Owner Name": v.get("displayName"), + "User Principal Name": v.get("userPrincipalName"), + "Mail": v.get("mail"), + "Job Title": v.get("jobTitle"), + "Office Location": v.get("officeLocation"), + "Mobile Phone": v.get("mobilePhone"), + "Business Phones": str(v.get("businessPhones")), + "Preferred Language": v.get("preferredLanguage"), + "Given Name": v.get("givenName"), + "Surname": v.get("surname"), + } + ) if rows: df = pd.DataFrame(rows, columns=list(columns.keys())) diff --git a/src/sempy_labs/graph/_teams.py b/src/sempy_labs/graph/_teams.py index e91f03f9..4b544e9f 100644 --- a/src/sempy_labs/graph/_teams.py +++ b/src/sempy_labs/graph/_teams.py @@ -23,7 +23,7 @@ def list_teams() -> pd.DataFrame: A pandas dataframe showing a list of teams and their properties. """ - result = _base_api(request="teams", client="graph").json() + result = _base_api(request="teams", client="graph", uses_pagination=True) columns = { "Team Id": "str", @@ -43,23 +43,24 @@ def list_teams() -> pd.DataFrame: df = _create_dataframe(columns=columns) rows = [] - for v in result.get("value"): - rows.append( - { - "Team Id": v.get("id"), - "Team Name": v.get("displayName"), - "Description": v.get("description"), - "Creation Date Time": v.get("createdDateTime"), - "Classification": v.get("classification"), - "Specialization": v.get("specialization"), - "Visibility": v.get("visibility"), - "Web Url": v.get("webUrl"), - "Archived": v.get("isArchived"), - "Favorite By Me": v.get("isFavoriteByMe"), - "Discoverable By Me": v.get("isDiscoverableByMe"), - "Member Count": v.get("memberCount"), - } - ) + for r in result: + for v in r.get("value", []): + rows.append( + { + "Team Id": v.get("id"), + "Team Name": v.get("displayName"), + "Description": v.get("description"), + "Creation Date Time": v.get("createdDateTime"), + "Classification": v.get("classification"), + "Specialization": v.get("specialization"), + "Visibility": v.get("visibility"), + "Web Url": v.get("webUrl"), + "Archived": v.get("isArchived"), + "Favorite By Me": v.get("isFavoriteByMe"), + "Discoverable By Me": v.get("isDiscoverableByMe"), + "Member Count": v.get("memberCount"), + } + ) if rows: df = pd.DataFrame(rows, columns=list(columns.keys())) diff --git a/src/sempy_labs/graph/_users.py b/src/sempy_labs/graph/_users.py index 0902aaa4..d8715e46 100644 --- a/src/sempy_labs/graph/_users.py +++ b/src/sempy_labs/graph/_users.py @@ -8,6 +8,7 @@ _is_valid_uuid, _base_api, _create_dataframe, + _update_dataframe_datatypes, _mount, ) from sempy._utils._log import log @@ -91,7 +92,7 @@ def list_users() -> pd.DataFrame: A pandas dataframe showing a list of users and their properties. """ - result = _base_api(request="users", client="graph").json() + result = _base_api(request="users", client="graph", uses_pagination=True) columns = { "User Id": "string", @@ -108,21 +109,27 @@ def list_users() -> pd.DataFrame: df = _create_dataframe(columns=columns) - for v in result.get("value"): - new_data = { - "User Id": v.get("id"), - "User Principal Name": v.get("userPrincipalName"), - "User Name": v.get("displayName"), - "Mail": v.get("mail"), - "Job Title": v.get("jobTitle"), - "Office Location": v.get("officeLocation"), - "Mobile Phone": v.get("mobilePhone"), - "Business Phones": str(v.get("businessPhones")), - "Preferred Language": v.get("preferredLanguage"), - "Surname": v.get("surname"), - } - - df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True) + rows = [] + for r in result: + for v in r.get("value", []): + rows.append( + { + "User Id": v.get("id"), + "User Principal Name": v.get("userPrincipalName"), + "User Name": v.get("displayName"), + "Mail": v.get("mail"), + "Job Title": v.get("jobTitle"), + "Office Location": v.get("officeLocation"), + "Mobile Phone": v.get("mobilePhone"), + "Business Phones": str(v.get("businessPhones")), + "Preferred Language": v.get("preferredLanguage"), + "Surname": v.get("surname"), + } + ) + + if rows: + df = pd.DataFrame(rows, columns=list(columns.keys())) + _update_dataframe_datatypes(dataframe=df, column_map=columns) return df