Skip to content

Commit fed9461

Browse files
authored
Graph API pagination (#890)
* Added Graph API pagination * black format
1 parent 5f49bbc commit fed9461

File tree

4 files changed

+127
-88
lines changed

4 files changed

+127
-88
lines changed

src/sempy_labs/_helper_functions.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,27 @@ def pagination(client, response):
16191619
return responses
16201620

16211621

1622+
def graph_pagination(response, headers):
1623+
1624+
responses = []
1625+
response_json = response.json()
1626+
responses.append(response_json)
1627+
1628+
# Check for pagination
1629+
odata_next_link = response_json.get("@odata.nextLink")
1630+
1631+
# Loop to handle pagination
1632+
while odata_next_link is not None:
1633+
response = requests.get(odata_next_link, headers=headers)
1634+
response_json = response.json()
1635+
responses.append(response_json)
1636+
1637+
# Update the odata next link for the next iteration
1638+
odata_next_link = response_json.get("@odata.nextLink")
1639+
1640+
return responses
1641+
1642+
16221643
def resolve_deployment_pipeline_id(deployment_pipeline: str | UUID) -> UUID:
16231644
"""
16241645
Obtains the Id for a given deployment pipeline.
@@ -2254,7 +2275,10 @@ def get_token(self, *scopes, **kwargs) -> AccessToken:
22542275
if response.status_code not in status_codes:
22552276
raise FabricHTTPException(response)
22562277
if uses_pagination:
2257-
responses = pagination(c, response)
2278+
if client == "graph":
2279+
responses = graph_pagination(response, headers)
2280+
else:
2281+
responses = pagination(c, response)
22582282
return responses
22592283
else:
22602284
return response

src/sempy_labs/graph/_groups.py

Lines changed: 60 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def list_groups() -> pd.DataFrame:
5555
A pandas dataframe showing a list of groups and their properties.
5656
"""
5757

58-
result = _base_api(request="groups", client="graph").json()
58+
result = _base_api(request="groups", client="graph", uses_pagination=True)
5959

6060
columns = {
6161
"Group Id": "string",
@@ -76,24 +76,25 @@ def list_groups() -> pd.DataFrame:
7676
df = _create_dataframe(columns=columns)
7777

7878
rows = []
79-
for v in result.get("value"):
80-
rows.append(
81-
{
82-
"Group Id": v.get("id"),
83-
"Group Name": v.get("displayName"),
84-
"Mail": v.get("mail"),
85-
"Description": v.get("description"),
86-
"Classification": v.get("classification"),
87-
"Mail Enabled": v.get("mailEnabled"),
88-
"Security Enabled": v.get("securityEnabled"),
89-
"Created Date Time": v.get("createdDateTime"),
90-
"Expiration Date Time": v.get("expirationDateTime"),
91-
"Renewed Date Time": v.get("renewedDateTime"),
92-
"Deleted Date Time": v.get("deletedDateTime"),
93-
"Visibility": v.get("visibility"),
94-
"Security Identifier": v.get("securityIdentifier"),
95-
}
96-
)
79+
for r in result:
80+
for v in r.get("value", []):
81+
rows.append(
82+
{
83+
"Group Id": v.get("id"),
84+
"Group Name": v.get("displayName"),
85+
"Mail": v.get("mail"),
86+
"Description": v.get("description"),
87+
"Classification": v.get("classification"),
88+
"Mail Enabled": v.get("mailEnabled"),
89+
"Security Enabled": v.get("securityEnabled"),
90+
"Created Date Time": v.get("createdDateTime"),
91+
"Expiration Date Time": v.get("expirationDateTime"),
92+
"Renewed Date Time": v.get("renewedDateTime"),
93+
"Deleted Date Time": v.get("deletedDateTime"),
94+
"Visibility": v.get("visibility"),
95+
"Security Identifier": v.get("securityIdentifier"),
96+
}
97+
)
9798

9899
if rows:
99100
df = pd.DataFrame(rows, columns=list(columns.keys()))
@@ -190,7 +191,9 @@ def list_group_members(group: str | UUID) -> pd.DataFrame:
190191

191192
group_id = resolve_group_id(group)
192193

193-
result = _base_api(request=f"groups/{group_id}/members", client="graph").json()
194+
result = _base_api(
195+
request=f"groups/{group_id}/members", client="graph", uses_pagination=True
196+
)
194197

195198
columns = {
196199
"Member Id": "string",
@@ -209,22 +212,23 @@ def list_group_members(group: str | UUID) -> pd.DataFrame:
209212
df = _create_dataframe(columns=columns)
210213

211214
rows = []
212-
for v in result.get("value"):
213-
rows.append(
214-
{
215-
"Member Id": v.get("id"),
216-
"Member Name": v.get("displayName"),
217-
"User Principal Name": v.get("userPrincipalName"),
218-
"Mail": v.get("mail"),
219-
"Job Title": v.get("jobTitle"),
220-
"Office Location": v.get("officeLocation"),
221-
"Mobile Phone": v.get("mobilePhone"),
222-
"Business Phones": str(v.get("businessPhones")),
223-
"Preferred Language": v.get("preferredLanguage"),
224-
"Given Name": v.get("givenName"),
225-
"Surname": v.get("surname"),
226-
}
227-
)
215+
for r in result:
216+
for v in r.get("value", []):
217+
rows.append(
218+
{
219+
"Member Id": v.get("id"),
220+
"Member Name": v.get("displayName"),
221+
"User Principal Name": v.get("userPrincipalName"),
222+
"Mail": v.get("mail"),
223+
"Job Title": v.get("jobTitle"),
224+
"Office Location": v.get("officeLocation"),
225+
"Mobile Phone": v.get("mobilePhone"),
226+
"Business Phones": str(v.get("businessPhones")),
227+
"Preferred Language": v.get("preferredLanguage"),
228+
"Given Name": v.get("givenName"),
229+
"Surname": v.get("surname"),
230+
}
231+
)
228232

229233
if rows:
230234
df = pd.DataFrame(rows, columns=list(columns.keys()))
@@ -254,7 +258,9 @@ def list_group_owners(group: str | UUID) -> pd.DataFrame:
254258

255259
group_id = resolve_group_id(group)
256260

257-
result = _base_api(request=f"groups/{group_id}/owners", client="graph").json()
261+
result = _base_api(
262+
request=f"groups/{group_id}/owners", client="graph", uses_pagination=True
263+
)
258264

259265
columns = {
260266
"Owner Id": "string",
@@ -273,22 +279,23 @@ def list_group_owners(group: str | UUID) -> pd.DataFrame:
273279
df = _create_dataframe(columns=columns)
274280

275281
rows = []
276-
for v in result.get("value"):
277-
rows.append(
278-
{
279-
"Owner Id": v.get("id"),
280-
"Owner Name": v.get("displayName"),
281-
"User Principal Name": v.get("userPrincipalName"),
282-
"Mail": v.get("mail"),
283-
"Job Title": v.get("jobTitle"),
284-
"Office Location": v.get("officeLocation"),
285-
"Mobile Phone": v.get("mobilePhone"),
286-
"Business Phones": str(v.get("businessPhones")),
287-
"Preferred Language": v.get("preferredLanguage"),
288-
"Given Name": v.get("givenName"),
289-
"Surname": v.get("surname"),
290-
}
291-
)
282+
for r in result:
283+
for v in r.get("value", []):
284+
rows.append(
285+
{
286+
"Owner Id": v.get("id"),
287+
"Owner Name": v.get("displayName"),
288+
"User Principal Name": v.get("userPrincipalName"),
289+
"Mail": v.get("mail"),
290+
"Job Title": v.get("jobTitle"),
291+
"Office Location": v.get("officeLocation"),
292+
"Mobile Phone": v.get("mobilePhone"),
293+
"Business Phones": str(v.get("businessPhones")),
294+
"Preferred Language": v.get("preferredLanguage"),
295+
"Given Name": v.get("givenName"),
296+
"Surname": v.get("surname"),
297+
}
298+
)
292299

293300
if rows:
294301
df = pd.DataFrame(rows, columns=list(columns.keys()))

src/sempy_labs/graph/_teams.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def list_teams() -> pd.DataFrame:
2323
A pandas dataframe showing a list of teams and their properties.
2424
"""
2525

26-
result = _base_api(request="teams", client="graph").json()
26+
result = _base_api(request="teams", client="graph", uses_pagination=True)
2727

2828
columns = {
2929
"Team Id": "str",
@@ -43,23 +43,24 @@ def list_teams() -> pd.DataFrame:
4343
df = _create_dataframe(columns=columns)
4444

4545
rows = []
46-
for v in result.get("value"):
47-
rows.append(
48-
{
49-
"Team Id": v.get("id"),
50-
"Team Name": v.get("displayName"),
51-
"Description": v.get("description"),
52-
"Creation Date Time": v.get("createdDateTime"),
53-
"Classification": v.get("classification"),
54-
"Specialization": v.get("specialization"),
55-
"Visibility": v.get("visibility"),
56-
"Web Url": v.get("webUrl"),
57-
"Archived": v.get("isArchived"),
58-
"Favorite By Me": v.get("isFavoriteByMe"),
59-
"Discoverable By Me": v.get("isDiscoverableByMe"),
60-
"Member Count": v.get("memberCount"),
61-
}
62-
)
46+
for r in result:
47+
for v in r.get("value", []):
48+
rows.append(
49+
{
50+
"Team Id": v.get("id"),
51+
"Team Name": v.get("displayName"),
52+
"Description": v.get("description"),
53+
"Creation Date Time": v.get("createdDateTime"),
54+
"Classification": v.get("classification"),
55+
"Specialization": v.get("specialization"),
56+
"Visibility": v.get("visibility"),
57+
"Web Url": v.get("webUrl"),
58+
"Archived": v.get("isArchived"),
59+
"Favorite By Me": v.get("isFavoriteByMe"),
60+
"Discoverable By Me": v.get("isDiscoverableByMe"),
61+
"Member Count": v.get("memberCount"),
62+
}
63+
)
6364

6465
if rows:
6566
df = pd.DataFrame(rows, columns=list(columns.keys()))

src/sempy_labs/graph/_users.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
_is_valid_uuid,
99
_base_api,
1010
_create_dataframe,
11+
_update_dataframe_datatypes,
1112
_mount,
1213
)
1314
from sempy._utils._log import log
@@ -91,7 +92,7 @@ def list_users() -> pd.DataFrame:
9192
A pandas dataframe showing a list of users and their properties.
9293
"""
9394

94-
result = _base_api(request="users", client="graph").json()
95+
result = _base_api(request="users", client="graph", uses_pagination=True)
9596

9697
columns = {
9798
"User Id": "string",
@@ -108,21 +109,27 @@ def list_users() -> pd.DataFrame:
108109

109110
df = _create_dataframe(columns=columns)
110111

111-
for v in result.get("value"):
112-
new_data = {
113-
"User Id": v.get("id"),
114-
"User Principal Name": v.get("userPrincipalName"),
115-
"User Name": v.get("displayName"),
116-
"Mail": v.get("mail"),
117-
"Job Title": v.get("jobTitle"),
118-
"Office Location": v.get("officeLocation"),
119-
"Mobile Phone": v.get("mobilePhone"),
120-
"Business Phones": str(v.get("businessPhones")),
121-
"Preferred Language": v.get("preferredLanguage"),
122-
"Surname": v.get("surname"),
123-
}
124-
125-
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
112+
rows = []
113+
for r in result:
114+
for v in r.get("value", []):
115+
rows.append(
116+
{
117+
"User Id": v.get("id"),
118+
"User Principal Name": v.get("userPrincipalName"),
119+
"User Name": v.get("displayName"),
120+
"Mail": v.get("mail"),
121+
"Job Title": v.get("jobTitle"),
122+
"Office Location": v.get("officeLocation"),
123+
"Mobile Phone": v.get("mobilePhone"),
124+
"Business Phones": str(v.get("businessPhones")),
125+
"Preferred Language": v.get("preferredLanguage"),
126+
"Surname": v.get("surname"),
127+
}
128+
)
129+
130+
if rows:
131+
df = pd.DataFrame(rows, columns=list(columns.keys()))
132+
_update_dataframe_datatypes(dataframe=df, column_map=columns)
126133

127134
return df
128135

0 commit comments

Comments
 (0)