semantic-link-labs 0.9.1__py3-none-any.whl → 0.9.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of semantic-link-labs might be problematic. Click here for more details.

Files changed (82) hide show
  1. {semantic_link_labs-0.9.1.dist-info → semantic_link_labs-0.9.2.dist-info}/METADATA +66 -8
  2. {semantic_link_labs-0.9.1.dist-info → semantic_link_labs-0.9.2.dist-info}/RECORD +82 -75
  3. sempy_labs/__init__.py +14 -12
  4. sempy_labs/_capacities.py +120 -142
  5. sempy_labs/_capacity_migration.py +61 -94
  6. sempy_labs/_clear_cache.py +9 -8
  7. sempy_labs/_connections.py +72 -105
  8. sempy_labs/_data_pipelines.py +47 -49
  9. sempy_labs/_dataflows.py +45 -51
  10. sempy_labs/_dax.py +228 -6
  11. sempy_labs/_delta_analyzer.py +303 -0
  12. sempy_labs/_deployment_pipelines.py +72 -66
  13. sempy_labs/_environments.py +39 -36
  14. sempy_labs/_eventhouses.py +35 -35
  15. sempy_labs/_eventstreams.py +38 -39
  16. sempy_labs/_external_data_shares.py +29 -42
  17. sempy_labs/_gateways.py +57 -101
  18. sempy_labs/_generate_semantic_model.py +22 -30
  19. sempy_labs/_git.py +46 -66
  20. sempy_labs/_graphQL.py +95 -0
  21. sempy_labs/_helper_functions.py +175 -30
  22. sempy_labs/_job_scheduler.py +47 -59
  23. sempy_labs/_kql_databases.py +27 -34
  24. sempy_labs/_kql_querysets.py +23 -30
  25. sempy_labs/_list_functions.py +262 -164
  26. sempy_labs/_managed_private_endpoints.py +52 -47
  27. sempy_labs/_mirrored_databases.py +110 -134
  28. sempy_labs/_mirrored_warehouses.py +13 -13
  29. sempy_labs/_ml_experiments.py +36 -36
  30. sempy_labs/_ml_models.py +37 -38
  31. sempy_labs/_model_dependencies.py +2 -0
  32. sempy_labs/_notebooks.py +28 -29
  33. sempy_labs/_one_lake_integration.py +2 -0
  34. sempy_labs/_query_scale_out.py +63 -81
  35. sempy_labs/_refresh_semantic_model.py +12 -14
  36. sempy_labs/_spark.py +54 -79
  37. sempy_labs/_sql.py +7 -11
  38. sempy_labs/_vertipaq.py +8 -3
  39. sempy_labs/_warehouses.py +30 -33
  40. sempy_labs/_workloads.py +15 -20
  41. sempy_labs/_workspace_identity.py +13 -17
  42. sempy_labs/_workspaces.py +49 -48
  43. sempy_labs/admin/__init__.py +2 -0
  44. sempy_labs/admin/_basic_functions.py +244 -281
  45. sempy_labs/admin/_domains.py +188 -103
  46. sempy_labs/admin/_external_data_share.py +26 -31
  47. sempy_labs/admin/_git.py +17 -22
  48. sempy_labs/admin/_items.py +34 -48
  49. sempy_labs/admin/_scanner.py +20 -13
  50. sempy_labs/directlake/_directlake_schema_compare.py +2 -0
  51. sempy_labs/directlake/_dl_helper.py +10 -11
  52. sempy_labs/directlake/_generate_shared_expression.py +4 -5
  53. sempy_labs/directlake/_get_directlake_lakehouse.py +1 -0
  54. sempy_labs/directlake/_list_directlake_model_calc_tables.py +1 -0
  55. sempy_labs/directlake/_show_unsupported_directlake_objects.py +2 -0
  56. sempy_labs/directlake/_warm_cache.py +2 -0
  57. sempy_labs/graph/__init__.py +33 -0
  58. sempy_labs/graph/_groups.py +402 -0
  59. sempy_labs/graph/_teams.py +113 -0
  60. sempy_labs/graph/_users.py +191 -0
  61. sempy_labs/lakehouse/__init__.py +4 -0
  62. sempy_labs/lakehouse/_get_lakehouse_columns.py +10 -10
  63. sempy_labs/lakehouse/_get_lakehouse_tables.py +14 -20
  64. sempy_labs/lakehouse/_lakehouse.py +101 -4
  65. sempy_labs/lakehouse/_shortcuts.py +42 -20
  66. sempy_labs/migration/__init__.py +4 -0
  67. sempy_labs/migration/_direct_lake_to_import.py +66 -0
  68. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +1 -0
  69. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +1 -0
  70. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +1 -0
  71. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +2 -0
  72. sempy_labs/report/_download_report.py +8 -13
  73. sempy_labs/report/_generate_report.py +49 -46
  74. sempy_labs/report/_paginated.py +20 -26
  75. sempy_labs/report/_report_functions.py +50 -45
  76. sempy_labs/report/_report_list_functions.py +2 -0
  77. sempy_labs/report/_report_rebind.py +6 -10
  78. sempy_labs/report/_reportwrapper.py +187 -220
  79. sempy_labs/tom/_model.py +8 -5
  80. {semantic_link_labs-0.9.1.dist-info → semantic_link_labs-0.9.2.dist-info}/LICENSE +0 -0
  81. {semantic_link_labs-0.9.1.dist-info → semantic_link_labs-0.9.2.dist-info}/WHEEL +0 -0
  82. {semantic_link_labs-0.9.1.dist-info → semantic_link_labs-0.9.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,402 @@
1
+ import pandas as pd
2
+ from uuid import UUID
3
+ from sempy_labs._helper_functions import (
4
+ _is_valid_uuid,
5
+ _base_api,
6
+ _create_dataframe,
7
+ _update_dataframe_datatypes,
8
+ )
9
+ import sempy_labs._icons as icons
10
+ from typing import List, Literal
11
+
12
+
13
+ def resolve_group_id(group: str | UUID) -> UUID:
14
+ """
15
+ Resolves the group ID from the group name or ID.
16
+
17
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
18
+
19
+ Parameters
20
+ ----------
21
+ group : str | uuid.UUID
22
+ The group name or ID.
23
+
24
+ Returns
25
+ -------
26
+ uuid.UUID
27
+ The group ID.
28
+ """
29
+ if _is_valid_uuid(group):
30
+ group_id = group
31
+ else:
32
+ dfG = list_groups()
33
+ dfG_filt = dfG[dfG["Group Name"] == group]
34
+ if dfG_filt.empty:
35
+ raise ValueError(f"{icons.red_dot} The '{group}' group does not exist.")
36
+ group_id = dfG_filt["Group Id"].iloc[0]
37
+
38
+ return group_id
39
+
40
+
41
+ def list_groups() -> pd.DataFrame:
42
+ """
43
+ Shows a list of groups and their properties.
44
+
45
+ This is a wrapper function for the following API: `List groups <https://learn.microsoft.com/graph/api/group-list>`_.
46
+
47
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
48
+
49
+ Returns
50
+ -------
51
+ pandas.DataFrame
52
+ A pandas dataframe showing a list of groups and their properties.
53
+ """
54
+
55
+ result = _base_api(request="groups", client="graph").json()
56
+
57
+ columns = {
58
+ "Group Id": "string",
59
+ "Group Name": "string",
60
+ "Mail": "string",
61
+ "Description": "string",
62
+ "Classification": "string",
63
+ "Mail Enabled": "bool",
64
+ "Security Enabled": "bool",
65
+ "Created Date Time": "datetime",
66
+ "Expiration Date Time": "string",
67
+ "Deleted Date Time": "string",
68
+ "Renewed Date Time": "string",
69
+ "Visibility": "string",
70
+ "Security Identifier": "string",
71
+ }
72
+
73
+ df = _create_dataframe(columns=columns)
74
+
75
+ for v in result.get("value"):
76
+ new_data = {
77
+ "Group Id": v.get("id"),
78
+ "Group Name": v.get("displayName"),
79
+ "Mail": v.get("mail"),
80
+ "Description": v.get("description"),
81
+ "Classification": v.get("classification"),
82
+ "Mail Enabled": v.get("mailEnabled"),
83
+ "Security Enabled": v.get("securityEnabled"),
84
+ "Created Date Time": v.get("createdDateTime"),
85
+ "Expiration Date Time": v.get("expirationDateTime"),
86
+ "Renewed Date Time": v.get("renewedDateTime"),
87
+ "Deleted Date Time": v.get("deletedDateTime"),
88
+ "Visibility": v.get("visibility"),
89
+ "Security Identifier": v.get("securityIdentifier"),
90
+ }
91
+
92
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
93
+
94
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
95
+
96
+ return df
97
+
98
+
99
+ def _get_group(group_id: UUID) -> pd.DataFrame:
100
+ """
101
+ Shows a list of groups and their properties.
102
+
103
+ This is a wrapper function for the following API: `Get group <https://learn.microsoft.com/graph/api/group-get>`_.
104
+
105
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
106
+
107
+ Parameters
108
+ ----------
109
+ group_id : uuid.UUID
110
+ The group ID.
111
+
112
+ Returns
113
+ -------
114
+ pandas.DataFrame
115
+ A pandas dataframe showing a list of groups and their properties.
116
+ """
117
+
118
+ result = _base_api(request=f"groups/{group_id}", client="graph").json()
119
+
120
+ columns = {
121
+ "Group Id": "string",
122
+ "Group Name": "string",
123
+ "Mail": "string",
124
+ "Description": "string",
125
+ "Classification": "string",
126
+ "Mail Enabled": "bool",
127
+ "Security Enabled": "bool",
128
+ "Created Date Time": "datetime",
129
+ "Expiration Date Time": "string",
130
+ "Deleted Date Time": "string",
131
+ "Renewed Date Time": "string",
132
+ "Visibility": "string",
133
+ "Security Identifier": "string",
134
+ }
135
+ df = _create_dataframe(columns=columns)
136
+
137
+ for v in result.get("value"):
138
+ new_data = {
139
+ "Group Id": v.get("id"),
140
+ "Group Name": v.get("displayName"),
141
+ "Mail": v.get("mail"),
142
+ "Description": v.get("description"),
143
+ "Classification": v.get("classification"),
144
+ "Mail Enabled": v.get("mailEnabled"),
145
+ "Security Enabled": v.get("securityEnabled"),
146
+ "Created Date Time": v.get("createdDateTime"),
147
+ "Expiration Date Time": v.get("expirationDateTime"),
148
+ "Deleted Date Time": v.get("deletedDateTime"),
149
+ "Renewed Date Time": v.get("renewedDateTime"),
150
+ "Visibility": v.get("visibility"),
151
+ "Security Identifier": v.get("securityIdentifier"),
152
+ }
153
+
154
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
155
+
156
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
157
+
158
+ return df
159
+
160
+
161
+ def list_group_members(group: str | UUID) -> pd.DataFrame:
162
+ """
163
+ Shows a list of the members of a group.
164
+
165
+ This is a wrapper function for the following API: `List group members <https://learn.microsoft.com/graph/api/group-list-members>`_.
166
+
167
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
168
+
169
+ Parameters
170
+ ----------
171
+ group : str | uuid.UUID
172
+ The group name or ID.
173
+
174
+ Returns
175
+ -------
176
+ pandas.DataFrame
177
+ A pandas dataframe showing a list of the members of a group.
178
+ """
179
+
180
+ group_id = resolve_group_id(group)
181
+
182
+ result = _base_api(request=f"groups/{group_id}/members", client="graph").json()
183
+
184
+ columns = {
185
+ "Member Id": "string",
186
+ "Member Name": "string",
187
+ "User Principal Name": "string",
188
+ "Mail": "string",
189
+ "Job Title": "string",
190
+ "Office Location": "string",
191
+ "Mobile Phone": "string",
192
+ "Business Phones": "string",
193
+ "Preferred Language": "string",
194
+ "Given Name": "string",
195
+ "Surname": "string",
196
+ }
197
+
198
+ df = _create_dataframe(columns=columns)
199
+
200
+ for v in result.get("value"):
201
+ new_data = {
202
+ "Member Id": v.get("id"),
203
+ "Member Name": v.get("displayName"),
204
+ "User Principal Name": v.get("userPrincipalName"),
205
+ "Mail": v.get("mail"),
206
+ "Job Title": v.get("jobTitle"),
207
+ "Office Location": v.get("officeLocation"),
208
+ "Mobile Phone": v.get("mobilePhone"),
209
+ "Business Phones": str(v.get("businessPhones")),
210
+ "Preferred Language": v.get("preferredLanguage"),
211
+ "Given Name": v.get("givenName"),
212
+ "Surname": v.get("surname"),
213
+ }
214
+
215
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
216
+
217
+ return df
218
+
219
+
220
+ def list_group_owners(group: str | UUID) -> pd.DataFrame:
221
+ """
222
+ Shows a list of the owners of a group.
223
+
224
+ This is a wrapper function for the following API: `List group owners <https://learn.microsoft.com/graph/api/group-list-owners>`_.
225
+
226
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
227
+
228
+ Parameters
229
+ ----------
230
+ group : str | uuid.UUID
231
+ The group name or ID.
232
+
233
+ Returns
234
+ -------
235
+ pandas.DataFrame
236
+ A pandas dataframe showing a list of the owners of a group.
237
+ """
238
+
239
+ group_id = resolve_group_id(group)
240
+
241
+ result = _base_api(request=f"groups/{group_id}/owners", client="graph").json()
242
+
243
+ columns = {
244
+ "Owner Id": "string",
245
+ "Owner Name": "string",
246
+ "User Principal Name": "string",
247
+ "Mail": "string",
248
+ "Job Title": "string",
249
+ "Office Location": "string",
250
+ "Mobile Phone": "string",
251
+ "Business Phones": "string",
252
+ "Preferred Language": "string",
253
+ "Given Name": "string",
254
+ "Surname": "string",
255
+ }
256
+
257
+ df = _create_dataframe(columns=columns)
258
+
259
+ for v in result.get("value"):
260
+ new_data = {
261
+ "Owner Id": v.get("id"),
262
+ "Owner Name": v.get("displayName"),
263
+ "User Principal Name": v.get("userPrincipalName"),
264
+ "Mail": v.get("mail"),
265
+ "Job Title": v.get("jobTitle"),
266
+ "Office Location": v.get("officeLocation"),
267
+ "Mobile Phone": v.get("mobilePhone"),
268
+ "Business Phones": str(v.get("businessPhones")),
269
+ "Preferred Language": v.get("preferredLanguage"),
270
+ "Given Name": v.get("givenName"),
271
+ "Surname": v.get("surname"),
272
+ }
273
+
274
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
275
+
276
+ return df
277
+
278
+
279
+ def _base_add_to_group(
280
+ group: str | UUID,
281
+ object: str | UUID,
282
+ object_type: Literal["members", "owners"],
283
+ ):
284
+
285
+ from sempy_labs.graph._users import resolve_user_id
286
+
287
+ object_list = []
288
+
289
+ if isinstance(object, str):
290
+ object = [object]
291
+
292
+ group_id = resolve_group_id(group)
293
+ url = f"groups/{group_id}/{object_type}/$ref"
294
+
295
+ for m in object:
296
+ if _is_valid_uuid(m):
297
+ member_id = m
298
+ else:
299
+ member_id = resolve_user_id(m)
300
+ if object_type == "members":
301
+ object_list.append(
302
+ f"https://graph.microsoft.com/v1.0/directoryObjects/{member_id}"
303
+ )
304
+ else:
305
+ object_list.append(f"https://graph.microsoft.com/v1.0/users/{member_id}")
306
+
307
+ # Must submit one request for each owner. Members can be sent in a single request.
308
+ if object_type == "members":
309
+ payload = {"members@odata.bind": object_list}
310
+
311
+ _base_api(
312
+ request=url,
313
+ client="graph",
314
+ payload=payload,
315
+ method="post",
316
+ status_codes=204,
317
+ )
318
+
319
+ else:
320
+ for o in object_list:
321
+ payload = {"odata.id": o}
322
+ _base_api(
323
+ request=url,
324
+ client="graph",
325
+ payload=payload,
326
+ method="post",
327
+ status_codes=204,
328
+ )
329
+
330
+ print(
331
+ f"{icons.green_dot} The {object} {object_type[:-1]}(s) have been added to the '{group}' group."
332
+ )
333
+
334
+
335
+ def add_group_members(
336
+ group: str | UUID,
337
+ user: str | UUID | List[str | UUID],
338
+ ):
339
+ """
340
+ Adds a member to a group.
341
+
342
+ This is a wrapper function for the following API: `Add members <https://learn.microsoft.com/graph/api/group-post-members>`_.
343
+
344
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
345
+
346
+ Parameters
347
+ ----------
348
+ group : str | uuid.UUID
349
+ The group name or ID.
350
+ user : str | uuid.UUID
351
+ The user ID or user principal name.
352
+ """
353
+
354
+ _base_add_to_group(group=group, object=user, object_type="members")
355
+
356
+
357
+ def add_group_owners(
358
+ group: str | UUID,
359
+ user: str | UUID | List[str | UUID],
360
+ ):
361
+ """
362
+ Adds an owner to a group.
363
+
364
+ This is a wrapper function for the following API: `Add owners <https://learn.microsoft.com/graph/api/group-post-owners>`_.
365
+
366
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
367
+
368
+ Parameters
369
+ ----------
370
+ group : str | uuid.UUID
371
+ The group name or ID.
372
+ user : str | uuid.UUID
373
+ The user ID or user principal name.
374
+ """
375
+
376
+ _base_add_to_group(group=group, object=user, object_type="owners")
377
+
378
+
379
+ def renew_group(group: str | UUID):
380
+ """
381
+ Renews the group.
382
+
383
+ This is a wrapper function for the following API: `Renew group <https://learn.microsoft.com/graph/api/group-post-renew>`_.
384
+
385
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
386
+
387
+ Parameters
388
+ ----------
389
+ group : str | uuid.UUID
390
+ The group name or ID.
391
+ """
392
+
393
+ group_id = resolve_group_id(group)
394
+
395
+ _base_api(
396
+ request=f"groups/{group_id}/renew",
397
+ client="graph",
398
+ method="post",
399
+ status_codes=204,
400
+ )
401
+
402
+ print(f"{icons.green_dot} The '{group}' group has been renewed.")
@@ -0,0 +1,113 @@
1
+ import pandas as pd
2
+ from uuid import UUID
3
+ from sempy_labs._helper_functions import (
4
+ _base_api,
5
+ _create_dataframe,
6
+ _update_dataframe_datatypes,
7
+ )
8
+
9
+
10
+ def list_teams() -> pd.DataFrame:
11
+ """
12
+ Shows a list of teams and their properties.
13
+
14
+ This is a wrapper function for the following API: `List teams <https://learn.microsoft.com/graph/api/teams-list>`_.
15
+
16
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
17
+
18
+ Returns
19
+ -------
20
+ pandas.DataFrame
21
+ A pandas dataframe showing a list of teams and their properties.
22
+ """
23
+
24
+ result = _base_api(request="teams", client="graph").json()
25
+
26
+ columns = {
27
+ "Team Id": "str",
28
+ "Team Name": "str",
29
+ "Description": "str",
30
+ "Creation Date Time": "datetime",
31
+ "Classification": "str",
32
+ "Specialization": "str",
33
+ "Visibility": "str",
34
+ "Web Url": "str",
35
+ "Archived": "bool",
36
+ "Favorite By Me": "bool",
37
+ "Discoverable By Me": "bool",
38
+ "Member Count": "int",
39
+ }
40
+
41
+ df = _create_dataframe(columns=columns)
42
+
43
+ for v in result.get("value"):
44
+ new_data = {
45
+ "Team Id": v.get("id"),
46
+ "Team Name": v.get("displayName"),
47
+ "Description": v.get("description"),
48
+ "Creation Date Time": v.get("createdDateTime"),
49
+ "Classification": v.get("classification"),
50
+ "Specialization": v.get("specialization"),
51
+ "Visibility": v.get("visibility"),
52
+ "Web Url": v.get("webUrl"),
53
+ "Archived": v.get("isArchived"),
54
+ "Favorite By Me": v.get("isFavoriteByMe"),
55
+ "Discoverable By Me": v.get("isDiscoverableByMe"),
56
+ "Member Count": v.get("memberCount"),
57
+ }
58
+
59
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
60
+
61
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
62
+
63
+ return df
64
+
65
+
66
+ def list_chats(user: str | UUID) -> pd.DataFrame:
67
+ """
68
+ In progress...
69
+ """
70
+
71
+ from sempy_labs.graph._users import resolve_user_id
72
+
73
+ user_id = resolve_user_id(user=user)
74
+ result = _base_api(request=f"users/{user_id}/chats", client="graph").json()
75
+
76
+ columns = {
77
+ "Chat Id": "str",
78
+ "Type": "str",
79
+ "Members": "str",
80
+ }
81
+
82
+ df = _create_dataframe(columns=columns)
83
+
84
+ for v in result.get("value"):
85
+ new_data = {
86
+ "Chat Id": v.get("id"),
87
+ "Type": v.get("chatType"),
88
+ "Members": v.get("members"),
89
+ }
90
+
91
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
92
+
93
+ return df
94
+
95
+
96
+ def send_teams_message(chat_id: str, message: str):
97
+ """
98
+ In progress...
99
+ """
100
+
101
+ payload = {
102
+ "body": {
103
+ "content": message,
104
+ }
105
+ }
106
+
107
+ _base_api(
108
+ request=f"chats/{chat_id}/messages",
109
+ client="graph",
110
+ method="post",
111
+ payload=payload,
112
+ status_codes=201,
113
+ )
@@ -0,0 +1,191 @@
1
+ import pandas as pd
2
+ from uuid import UUID
3
+ import sempy_labs._icons as icons
4
+ from typing import List
5
+ from sempy_labs._helper_functions import (
6
+ _is_valid_uuid,
7
+ _base_api,
8
+ _create_dataframe,
9
+ )
10
+
11
+
12
+ def resolve_user_id(user: str | UUID) -> UUID:
13
+ """
14
+ Resolves the user ID from the user principal name or ID.
15
+
16
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
17
+
18
+ Parameters
19
+ ----------
20
+ user : str | uuid.UUID
21
+ The user ID or user principal name.
22
+
23
+ Returns
24
+ -------
25
+ uuid.UUID
26
+ The user ID.
27
+ """
28
+
29
+ if _is_valid_uuid(user):
30
+ return user
31
+ else:
32
+ result = _base_api(request=f"users/{user}", client="graph").json()
33
+ return result.get("id")
34
+
35
+
36
+ def get_user(user: str | UUID) -> pd.DataFrame:
37
+ """
38
+ Shows properties of a given user.
39
+
40
+ This is a wrapper function for the following API: `Get a user <https://learn.microsoft.com/graph/api/user-get>`_.
41
+
42
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
43
+
44
+ Parameters
45
+ ----------
46
+ user : str | uuid.UUID
47
+ The user ID or user principal name.
48
+
49
+ Returns
50
+ -------
51
+ pandas.DataFrame
52
+ A pandas dataframe showing properties of a given user.
53
+ """
54
+
55
+ result = _base_api(request=f"users/{user}", client="graph").json()
56
+
57
+ new_data = {
58
+ "User Id": result.get("id"),
59
+ "User Principal Name": result.get("userPrincipalName"),
60
+ "User Name": result.get("displayName"),
61
+ "Mail": result.get("mail"),
62
+ "Job Title": result.get("jobTitle"),
63
+ "Office Location": result.get("officeLocation"),
64
+ "Mobile Phone": result.get("mobilePhone"),
65
+ "Business Phones": str(result.get("businessPhones")),
66
+ "Preferred Language": result.get("preferredLanguage"),
67
+ "Surname": result.get("surname"),
68
+ }
69
+
70
+ return pd.DataFrame([new_data])
71
+
72
+
73
+ def list_users() -> pd.DataFrame:
74
+ """
75
+ Shows a list of users and their properties.
76
+
77
+ This is a wrapper function for the following API: `List users <https://learn.microsoft.com/graph/api/user-list>`_.
78
+
79
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
80
+
81
+ Returns
82
+ -------
83
+ pandas.DataFrame
84
+ A pandas dataframe showing a list of users and their properties.
85
+ """
86
+
87
+ result = _base_api(request="users", client="graph").json()
88
+
89
+ columns = {
90
+ "User Id": "string",
91
+ "User Principal Name": "string",
92
+ "User Name": "string",
93
+ "Mail": "string",
94
+ "Job Title": "string",
95
+ "Office Location": "string",
96
+ "Mobile Phone": "string",
97
+ "Business Phones": "string",
98
+ "Preferred Language": "string",
99
+ "Surname": "string",
100
+ }
101
+
102
+ df = _create_dataframe(columns=columns)
103
+
104
+ for v in result.get("value"):
105
+ new_data = {
106
+ "User Id": v.get("id"),
107
+ "User Principal Name": v.get("userPrincipalName"),
108
+ "User Name": v.get("displayName"),
109
+ "Mail": v.get("mail"),
110
+ "Job Title": v.get("jobTitle"),
111
+ "Office Location": v.get("officeLocation"),
112
+ "Mobile Phone": v.get("mobilePhone"),
113
+ "Business Phones": str(v.get("businessPhones")),
114
+ "Preferred Language": v.get("preferredLanguage"),
115
+ "Surname": v.get("surname"),
116
+ }
117
+
118
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
119
+
120
+ return df
121
+
122
+
123
+ def send_mail(
124
+ user: UUID | str,
125
+ subject: str,
126
+ to_recipients: str | List[str],
127
+ content: str,
128
+ cc_recipients: str | List[str] = None,
129
+ ):
130
+ """
131
+ Sends an email to the specified recipients.
132
+
133
+ This is a wrapper function for the following API: `user: sendMail <https://learn.microsoft.com/graph/api/user-sendmail>`_.
134
+
135
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
136
+
137
+ Parameters
138
+ ----------
139
+ user : uuid.UUID | str
140
+ The user ID or user principal name.
141
+ subject : str
142
+ The email subject.
143
+ to_recipients : str | List[str]
144
+ The email address of the recipients.
145
+ content : str
146
+ The email content.
147
+ cc_recipients : str | List[str], default=None
148
+ The email address of the CC recipients.
149
+ """
150
+
151
+ user_id = resolve_user_id(user=user)
152
+
153
+ if isinstance(to_recipients, str):
154
+ to_recipients = [to_recipients]
155
+
156
+ if isinstance(cc_recipients, str):
157
+ cc_recipients = [cc_recipients]
158
+
159
+ to_email_addresses = [
160
+ {"emailAddress": {"address": email}} for email in to_recipients
161
+ ]
162
+
163
+ cc_email_addresses = (
164
+ [{"emailAddress": {"address": email}} for email in cc_recipients]
165
+ if cc_recipients
166
+ else None
167
+ )
168
+
169
+ payload = {
170
+ "message": {
171
+ "subject": subject,
172
+ "body": {
173
+ "contentType": "Text",
174
+ "content": content,
175
+ },
176
+ "toRecipients": to_email_addresses,
177
+ },
178
+ }
179
+
180
+ if cc_email_addresses:
181
+ payload["message"]["ccRecipients"] = cc_email_addresses
182
+
183
+ _base_api(
184
+ request=f"users/{user_id}/sendMail",
185
+ client="graph",
186
+ status_codes=202,
187
+ payload=payload,
188
+ method="post",
189
+ )
190
+
191
+ print(f"{icons.green_dot} The email has been sent to {to_recipients}.")