semantic-link-labs 0.12.8__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.
Files changed (243) hide show
  1. semantic_link_labs-0.12.8.dist-info/METADATA +354 -0
  2. semantic_link_labs-0.12.8.dist-info/RECORD +243 -0
  3. semantic_link_labs-0.12.8.dist-info/WHEEL +5 -0
  4. semantic_link_labs-0.12.8.dist-info/licenses/LICENSE +21 -0
  5. semantic_link_labs-0.12.8.dist-info/top_level.txt +1 -0
  6. sempy_labs/__init__.py +606 -0
  7. sempy_labs/_a_lib_info.py +2 -0
  8. sempy_labs/_ai.py +437 -0
  9. sempy_labs/_authentication.py +264 -0
  10. sempy_labs/_bpa_translation/_model/_translations_am-ET.po +869 -0
  11. sempy_labs/_bpa_translation/_model/_translations_ar-AE.po +908 -0
  12. sempy_labs/_bpa_translation/_model/_translations_bg-BG.po +968 -0
  13. sempy_labs/_bpa_translation/_model/_translations_ca-ES.po +963 -0
  14. sempy_labs/_bpa_translation/_model/_translations_cs-CZ.po +943 -0
  15. sempy_labs/_bpa_translation/_model/_translations_da-DK.po +945 -0
  16. sempy_labs/_bpa_translation/_model/_translations_de-DE.po +988 -0
  17. sempy_labs/_bpa_translation/_model/_translations_el-GR.po +993 -0
  18. sempy_labs/_bpa_translation/_model/_translations_es-ES.po +971 -0
  19. sempy_labs/_bpa_translation/_model/_translations_fa-IR.po +933 -0
  20. sempy_labs/_bpa_translation/_model/_translations_fi-FI.po +942 -0
  21. sempy_labs/_bpa_translation/_model/_translations_fr-FR.po +994 -0
  22. sempy_labs/_bpa_translation/_model/_translations_ga-IE.po +967 -0
  23. sempy_labs/_bpa_translation/_model/_translations_he-IL.po +902 -0
  24. sempy_labs/_bpa_translation/_model/_translations_hi-IN.po +944 -0
  25. sempy_labs/_bpa_translation/_model/_translations_hu-HU.po +963 -0
  26. sempy_labs/_bpa_translation/_model/_translations_id-ID.po +946 -0
  27. sempy_labs/_bpa_translation/_model/_translations_is-IS.po +939 -0
  28. sempy_labs/_bpa_translation/_model/_translations_it-IT.po +986 -0
  29. sempy_labs/_bpa_translation/_model/_translations_ja-JP.po +846 -0
  30. sempy_labs/_bpa_translation/_model/_translations_ko-KR.po +839 -0
  31. sempy_labs/_bpa_translation/_model/_translations_mt-MT.po +967 -0
  32. sempy_labs/_bpa_translation/_model/_translations_nl-NL.po +978 -0
  33. sempy_labs/_bpa_translation/_model/_translations_pl-PL.po +962 -0
  34. sempy_labs/_bpa_translation/_model/_translations_pt-BR.po +962 -0
  35. sempy_labs/_bpa_translation/_model/_translations_pt-PT.po +957 -0
  36. sempy_labs/_bpa_translation/_model/_translations_ro-RO.po +968 -0
  37. sempy_labs/_bpa_translation/_model/_translations_ru-RU.po +964 -0
  38. sempy_labs/_bpa_translation/_model/_translations_sk-SK.po +952 -0
  39. sempy_labs/_bpa_translation/_model/_translations_sl-SL.po +950 -0
  40. sempy_labs/_bpa_translation/_model/_translations_sv-SE.po +942 -0
  41. sempy_labs/_bpa_translation/_model/_translations_ta-IN.po +976 -0
  42. sempy_labs/_bpa_translation/_model/_translations_te-IN.po +947 -0
  43. sempy_labs/_bpa_translation/_model/_translations_th-TH.po +924 -0
  44. sempy_labs/_bpa_translation/_model/_translations_tr-TR.po +953 -0
  45. sempy_labs/_bpa_translation/_model/_translations_uk-UA.po +961 -0
  46. sempy_labs/_bpa_translation/_model/_translations_zh-CN.po +804 -0
  47. sempy_labs/_bpa_translation/_model/_translations_zu-ZA.po +969 -0
  48. sempy_labs/_capacities.py +1198 -0
  49. sempy_labs/_capacity_migration.py +660 -0
  50. sempy_labs/_clear_cache.py +351 -0
  51. sempy_labs/_connections.py +610 -0
  52. sempy_labs/_dashboards.py +69 -0
  53. sempy_labs/_data_access_security.py +98 -0
  54. sempy_labs/_data_pipelines.py +162 -0
  55. sempy_labs/_dataflows.py +668 -0
  56. sempy_labs/_dax.py +501 -0
  57. sempy_labs/_daxformatter.py +80 -0
  58. sempy_labs/_delta_analyzer.py +467 -0
  59. sempy_labs/_delta_analyzer_history.py +301 -0
  60. sempy_labs/_dictionary_diffs.py +221 -0
  61. sempy_labs/_documentation.py +147 -0
  62. sempy_labs/_domains.py +51 -0
  63. sempy_labs/_eventhouses.py +182 -0
  64. sempy_labs/_external_data_shares.py +230 -0
  65. sempy_labs/_gateways.py +521 -0
  66. sempy_labs/_generate_semantic_model.py +521 -0
  67. sempy_labs/_get_connection_string.py +84 -0
  68. sempy_labs/_git.py +543 -0
  69. sempy_labs/_graphQL.py +90 -0
  70. sempy_labs/_helper_functions.py +2833 -0
  71. sempy_labs/_icons.py +149 -0
  72. sempy_labs/_job_scheduler.py +609 -0
  73. sempy_labs/_kql_databases.py +149 -0
  74. sempy_labs/_kql_querysets.py +124 -0
  75. sempy_labs/_kusto.py +137 -0
  76. sempy_labs/_labels.py +124 -0
  77. sempy_labs/_list_functions.py +1720 -0
  78. sempy_labs/_managed_private_endpoints.py +253 -0
  79. sempy_labs/_mirrored_databases.py +416 -0
  80. sempy_labs/_mirrored_warehouses.py +60 -0
  81. sempy_labs/_ml_experiments.py +113 -0
  82. sempy_labs/_model_auto_build.py +140 -0
  83. sempy_labs/_model_bpa.py +557 -0
  84. sempy_labs/_model_bpa_bulk.py +378 -0
  85. sempy_labs/_model_bpa_rules.py +859 -0
  86. sempy_labs/_model_dependencies.py +343 -0
  87. sempy_labs/_mounted_data_factories.py +123 -0
  88. sempy_labs/_notebooks.py +441 -0
  89. sempy_labs/_one_lake_integration.py +151 -0
  90. sempy_labs/_onelake.py +131 -0
  91. sempy_labs/_query_scale_out.py +433 -0
  92. sempy_labs/_refresh_semantic_model.py +435 -0
  93. sempy_labs/_semantic_models.py +468 -0
  94. sempy_labs/_spark.py +455 -0
  95. sempy_labs/_sql.py +241 -0
  96. sempy_labs/_sql_audit_settings.py +207 -0
  97. sempy_labs/_sql_endpoints.py +214 -0
  98. sempy_labs/_tags.py +201 -0
  99. sempy_labs/_translations.py +43 -0
  100. sempy_labs/_user_delegation_key.py +44 -0
  101. sempy_labs/_utils.py +79 -0
  102. sempy_labs/_vertipaq.py +1021 -0
  103. sempy_labs/_vpax.py +388 -0
  104. sempy_labs/_warehouses.py +234 -0
  105. sempy_labs/_workloads.py +140 -0
  106. sempy_labs/_workspace_identity.py +72 -0
  107. sempy_labs/_workspaces.py +595 -0
  108. sempy_labs/admin/__init__.py +170 -0
  109. sempy_labs/admin/_activities.py +167 -0
  110. sempy_labs/admin/_apps.py +145 -0
  111. sempy_labs/admin/_artifacts.py +65 -0
  112. sempy_labs/admin/_basic_functions.py +463 -0
  113. sempy_labs/admin/_capacities.py +508 -0
  114. sempy_labs/admin/_dataflows.py +45 -0
  115. sempy_labs/admin/_datasets.py +186 -0
  116. sempy_labs/admin/_domains.py +522 -0
  117. sempy_labs/admin/_external_data_share.py +100 -0
  118. sempy_labs/admin/_git.py +72 -0
  119. sempy_labs/admin/_items.py +265 -0
  120. sempy_labs/admin/_labels.py +211 -0
  121. sempy_labs/admin/_reports.py +241 -0
  122. sempy_labs/admin/_scanner.py +118 -0
  123. sempy_labs/admin/_shared.py +82 -0
  124. sempy_labs/admin/_sharing_links.py +110 -0
  125. sempy_labs/admin/_tags.py +131 -0
  126. sempy_labs/admin/_tenant.py +503 -0
  127. sempy_labs/admin/_tenant_keys.py +89 -0
  128. sempy_labs/admin/_users.py +140 -0
  129. sempy_labs/admin/_workspaces.py +236 -0
  130. sempy_labs/deployment_pipeline/__init__.py +23 -0
  131. sempy_labs/deployment_pipeline/_items.py +580 -0
  132. sempy_labs/directlake/__init__.py +57 -0
  133. sempy_labs/directlake/_autosync.py +58 -0
  134. sempy_labs/directlake/_directlake_schema_compare.py +120 -0
  135. sempy_labs/directlake/_directlake_schema_sync.py +161 -0
  136. sempy_labs/directlake/_dl_helper.py +274 -0
  137. sempy_labs/directlake/_generate_shared_expression.py +94 -0
  138. sempy_labs/directlake/_get_directlake_lakehouse.py +62 -0
  139. sempy_labs/directlake/_get_shared_expression.py +34 -0
  140. sempy_labs/directlake/_guardrails.py +96 -0
  141. sempy_labs/directlake/_list_directlake_model_calc_tables.py +70 -0
  142. sempy_labs/directlake/_show_unsupported_directlake_objects.py +90 -0
  143. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +239 -0
  144. sempy_labs/directlake/_update_directlake_partition_entity.py +259 -0
  145. sempy_labs/directlake/_warm_cache.py +236 -0
  146. sempy_labs/dotnet_lib/dotnet.runtime.config.json +10 -0
  147. sempy_labs/environment/__init__.py +23 -0
  148. sempy_labs/environment/_items.py +212 -0
  149. sempy_labs/environment/_pubstage.py +223 -0
  150. sempy_labs/eventstream/__init__.py +37 -0
  151. sempy_labs/eventstream/_items.py +263 -0
  152. sempy_labs/eventstream/_topology.py +652 -0
  153. sempy_labs/graph/__init__.py +59 -0
  154. sempy_labs/graph/_groups.py +651 -0
  155. sempy_labs/graph/_sensitivity_labels.py +120 -0
  156. sempy_labs/graph/_teams.py +125 -0
  157. sempy_labs/graph/_user_licenses.py +96 -0
  158. sempy_labs/graph/_users.py +516 -0
  159. sempy_labs/graph_model/__init__.py +15 -0
  160. sempy_labs/graph_model/_background_jobs.py +63 -0
  161. sempy_labs/graph_model/_items.py +149 -0
  162. sempy_labs/lakehouse/__init__.py +67 -0
  163. sempy_labs/lakehouse/_blobs.py +247 -0
  164. sempy_labs/lakehouse/_get_lakehouse_columns.py +102 -0
  165. sempy_labs/lakehouse/_get_lakehouse_tables.py +274 -0
  166. sempy_labs/lakehouse/_helper.py +250 -0
  167. sempy_labs/lakehouse/_lakehouse.py +351 -0
  168. sempy_labs/lakehouse/_livy_sessions.py +143 -0
  169. sempy_labs/lakehouse/_materialized_lake_views.py +157 -0
  170. sempy_labs/lakehouse/_partitioning.py +165 -0
  171. sempy_labs/lakehouse/_schemas.py +217 -0
  172. sempy_labs/lakehouse/_shortcuts.py +440 -0
  173. sempy_labs/migration/__init__.py +35 -0
  174. sempy_labs/migration/_create_pqt_file.py +238 -0
  175. sempy_labs/migration/_direct_lake_to_import.py +105 -0
  176. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +398 -0
  177. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +148 -0
  178. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +533 -0
  179. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +172 -0
  180. sempy_labs/migration/_migration_validation.py +71 -0
  181. sempy_labs/migration/_refresh_calc_tables.py +131 -0
  182. sempy_labs/mirrored_azure_databricks_catalog/__init__.py +15 -0
  183. sempy_labs/mirrored_azure_databricks_catalog/_discover.py +213 -0
  184. sempy_labs/mirrored_azure_databricks_catalog/_refresh_catalog_metadata.py +45 -0
  185. sempy_labs/ml_model/__init__.py +23 -0
  186. sempy_labs/ml_model/_functions.py +427 -0
  187. sempy_labs/report/_BPAReportTemplate.json +232 -0
  188. sempy_labs/report/__init__.py +55 -0
  189. sempy_labs/report/_bpareporttemplate/.pbi/localSettings.json +9 -0
  190. sempy_labs/report/_bpareporttemplate/.platform +11 -0
  191. sempy_labs/report/_bpareporttemplate/StaticResources/SharedResources/BaseThemes/CY24SU06.json +710 -0
  192. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/page.json +11 -0
  193. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/1b08bce3bebabb0a27a8/visual.json +191 -0
  194. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/2f22ddb70c301693c165/visual.json +438 -0
  195. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/3b1182230aa6c600b43a/visual.json +127 -0
  196. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/58577ba6380c69891500/visual.json +576 -0
  197. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/a2a8fa5028b3b776c96c/visual.json +207 -0
  198. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/adfd47ef30652707b987/visual.json +506 -0
  199. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/b6a80ee459e716e170b1/visual.json +127 -0
  200. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/ce3130a721c020cc3d81/visual.json +513 -0
  201. sempy_labs/report/_bpareporttemplate/definition/pages/92735ae19b31712208ad/page.json +8 -0
  202. sempy_labs/report/_bpareporttemplate/definition/pages/92735ae19b31712208ad/visuals/66e60dfb526437cd78d1/visual.json +112 -0
  203. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/page.json +11 -0
  204. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/07deb8bce824e1be37d7/visual.json +513 -0
  205. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0b1c68838818b32ad03b/visual.json +352 -0
  206. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0c171de9d2683d10b930/visual.json +37 -0
  207. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0efa01be0510e40a645e/visual.json +542 -0
  208. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/6bf2f0eb830ab53cc668/visual.json +221 -0
  209. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/88d8141cb8500b60030c/visual.json +127 -0
  210. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/a753273590beed656a03/visual.json +576 -0
  211. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/b8fdc82cddd61ac447bc/visual.json +127 -0
  212. sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/page.json +9 -0
  213. sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/visuals/ce8532a7e25020271077/visual.json +38 -0
  214. sempy_labs/report/_bpareporttemplate/definition/pages/pages.json +10 -0
  215. sempy_labs/report/_bpareporttemplate/definition/report.json +176 -0
  216. sempy_labs/report/_bpareporttemplate/definition/version.json +4 -0
  217. sempy_labs/report/_bpareporttemplate/definition.pbir +14 -0
  218. sempy_labs/report/_download_report.py +76 -0
  219. sempy_labs/report/_export_report.py +257 -0
  220. sempy_labs/report/_generate_report.py +427 -0
  221. sempy_labs/report/_paginated.py +76 -0
  222. sempy_labs/report/_report_bpa.py +354 -0
  223. sempy_labs/report/_report_bpa_rules.py +115 -0
  224. sempy_labs/report/_report_functions.py +581 -0
  225. sempy_labs/report/_report_helper.py +227 -0
  226. sempy_labs/report/_report_list_functions.py +110 -0
  227. sempy_labs/report/_report_rebind.py +149 -0
  228. sempy_labs/report/_reportwrapper.py +3100 -0
  229. sempy_labs/report/_save_report.py +147 -0
  230. sempy_labs/snowflake_database/__init__.py +10 -0
  231. sempy_labs/snowflake_database/_items.py +105 -0
  232. sempy_labs/sql_database/__init__.py +21 -0
  233. sempy_labs/sql_database/_items.py +201 -0
  234. sempy_labs/sql_database/_mirroring.py +79 -0
  235. sempy_labs/theme/__init__.py +12 -0
  236. sempy_labs/theme/_org_themes.py +129 -0
  237. sempy_labs/tom/__init__.py +3 -0
  238. sempy_labs/tom/_model.py +5977 -0
  239. sempy_labs/variable_library/__init__.py +19 -0
  240. sempy_labs/variable_library/_functions.py +403 -0
  241. sempy_labs/warehouse/__init__.py +28 -0
  242. sempy_labs/warehouse/_items.py +234 -0
  243. sempy_labs/warehouse/_restore_points.py +309 -0
@@ -0,0 +1,59 @@
1
+ from ._groups import (
2
+ list_groups,
3
+ list_group_owners,
4
+ list_group_members,
5
+ add_group_members,
6
+ add_group_owners,
7
+ resolve_group_id,
8
+ renew_group,
9
+ create_group,
10
+ delete_group,
11
+ update_group,
12
+ list_group_transitive_members,
13
+ )
14
+ from ._users import (
15
+ resolve_user_id,
16
+ get_user,
17
+ list_users,
18
+ send_mail,
19
+ create_user,
20
+ delete_user,
21
+ update_user,
22
+ )
23
+ from ._teams import (
24
+ list_teams,
25
+ )
26
+ from ._sensitivity_labels import (
27
+ list_sensitivity_labels,
28
+ resolve_sensitivity_label_id,
29
+ )
30
+ from ._user_licenses import (
31
+ add_user_license,
32
+ remove_user_license,
33
+ )
34
+
35
+ __all__ = [
36
+ "list_groups",
37
+ "list_group_owners",
38
+ "list_group_members",
39
+ "add_group_members",
40
+ "add_group_owners",
41
+ "renew_group",
42
+ "resolve_group_id",
43
+ "resolve_user_id",
44
+ "get_user",
45
+ "list_users",
46
+ "send_mail",
47
+ "list_teams",
48
+ "create_user",
49
+ "create_group",
50
+ "delete_user",
51
+ "delete_group",
52
+ "update_user",
53
+ "update_group",
54
+ "list_sensitivity_labels",
55
+ "resolve_sensitivity_label_id",
56
+ "add_user_license",
57
+ "remove_user_license",
58
+ "list_group_transitive_members",
59
+ ]
@@ -0,0 +1,651 @@
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
+ from sempy._utils._log import log
10
+ import sempy_labs._icons as icons
11
+ from typing import List, Literal, Optional
12
+
13
+
14
+ @log
15
+ def resolve_group_id(group: str | UUID) -> UUID:
16
+ """
17
+ Resolves the group ID from the group name or ID.
18
+
19
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
20
+
21
+ Parameters
22
+ ----------
23
+ group : str | uuid.UUID
24
+ The group name or ID.
25
+
26
+ Returns
27
+ -------
28
+ uuid.UUID
29
+ The group ID.
30
+ """
31
+ if _is_valid_uuid(group):
32
+ group_id = group
33
+ else:
34
+ dfG = list_groups()
35
+ dfG_filt = dfG[dfG["Group Name"] == group]
36
+ if dfG_filt.empty:
37
+ raise ValueError(f"{icons.red_dot} The '{group}' group does not exist.")
38
+ group_id = dfG_filt["Group Id"].iloc[0]
39
+
40
+ return group_id
41
+
42
+
43
+ @log
44
+ def list_groups() -> pd.DataFrame:
45
+ """
46
+ Shows a list of groups and their properties.
47
+
48
+ This is a wrapper function for the following API: `List groups <https://learn.microsoft.com/graph/api/group-list>`_.
49
+
50
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
51
+
52
+ Returns
53
+ -------
54
+ pandas.DataFrame
55
+ A pandas dataframe showing a list of groups and their properties.
56
+ """
57
+
58
+ result = _base_api(request="groups", client="graph", uses_pagination=True)
59
+
60
+ columns = {
61
+ "Group Id": "string",
62
+ "Group Name": "string",
63
+ "Mail": "string",
64
+ "Description": "string",
65
+ "Classification": "string",
66
+ "Mail Enabled": "bool",
67
+ "Security Enabled": "bool",
68
+ "Created Date Time": "datetime",
69
+ "Expiration Date Time": "string",
70
+ "Deleted Date Time": "string",
71
+ "Renewed Date Time": "string",
72
+ "Visibility": "string",
73
+ "Security Identifier": "string",
74
+ }
75
+
76
+ df = _create_dataframe(columns=columns)
77
+
78
+ rows = []
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
+ )
98
+
99
+ if rows:
100
+ df = pd.DataFrame(rows, columns=list(columns.keys()))
101
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
102
+
103
+ return df
104
+
105
+
106
+ @log
107
+ def _get_group(group_id: UUID) -> pd.DataFrame:
108
+ """
109
+ Shows a list of groups and their properties.
110
+
111
+ This is a wrapper function for the following API: `Get group <https://learn.microsoft.com/graph/api/group-get>`_.
112
+
113
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
114
+
115
+ Parameters
116
+ ----------
117
+ group_id : uuid.UUID
118
+ The group ID.
119
+
120
+ Returns
121
+ -------
122
+ pandas.DataFrame
123
+ A pandas dataframe showing a list of groups and their properties.
124
+ """
125
+
126
+ result = _base_api(request=f"groups/{group_id}", client="graph").json()
127
+
128
+ columns = {
129
+ "Group Id": "string",
130
+ "Group Name": "string",
131
+ "Mail": "string",
132
+ "Description": "string",
133
+ "Classification": "string",
134
+ "Mail Enabled": "bool",
135
+ "Security Enabled": "bool",
136
+ "Created Date Time": "datetime",
137
+ "Expiration Date Time": "string",
138
+ "Deleted Date Time": "string",
139
+ "Renewed Date Time": "string",
140
+ "Visibility": "string",
141
+ "Security Identifier": "string",
142
+ }
143
+ df = _create_dataframe(columns=columns)
144
+
145
+ rows = []
146
+ for v in result.get("value"):
147
+ rows.append(
148
+ {
149
+ "Group Id": v.get("id"),
150
+ "Group Name": v.get("displayName"),
151
+ "Mail": v.get("mail"),
152
+ "Description": v.get("description"),
153
+ "Classification": v.get("classification"),
154
+ "Mail Enabled": v.get("mailEnabled"),
155
+ "Security Enabled": v.get("securityEnabled"),
156
+ "Created Date Time": v.get("createdDateTime"),
157
+ "Expiration Date Time": v.get("expirationDateTime"),
158
+ "Deleted Date Time": v.get("deletedDateTime"),
159
+ "Renewed Date Time": v.get("renewedDateTime"),
160
+ "Visibility": v.get("visibility"),
161
+ "Security Identifier": v.get("securityIdentifier"),
162
+ }
163
+ )
164
+
165
+ if rows:
166
+ df = pd.DataFrame(rows, columns=list(columns.keys()))
167
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
168
+
169
+ return df
170
+
171
+
172
+ @log
173
+ def list_group_members(group: str | UUID) -> pd.DataFrame:
174
+ """
175
+ Shows a list of the members of a group.
176
+
177
+ This is a wrapper function for the following API: `List group members <https://learn.microsoft.com/graph/api/group-list-members>`_.
178
+
179
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
180
+
181
+ Parameters
182
+ ----------
183
+ group : str | uuid.UUID
184
+ The group name or ID.
185
+
186
+ Returns
187
+ -------
188
+ pandas.DataFrame
189
+ A pandas dataframe showing a list of the members of a group.
190
+ """
191
+
192
+ group_id = resolve_group_id(group)
193
+
194
+ result = _base_api(
195
+ request=f"groups/{group_id}/members", client="graph", uses_pagination=True
196
+ )
197
+
198
+ columns = {
199
+ "Member Id": "string",
200
+ "Member Name": "string",
201
+ "User Principal Name": "string",
202
+ "Mail": "string",
203
+ "Job Title": "string",
204
+ "Office Location": "string",
205
+ "Mobile Phone": "string",
206
+ "Business Phones": "string",
207
+ "Preferred Language": "string",
208
+ "Given Name": "string",
209
+ "Surname": "string",
210
+ }
211
+
212
+ df = _create_dataframe(columns=columns)
213
+
214
+ rows = []
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
+ )
232
+
233
+ if rows:
234
+ df = pd.DataFrame(rows, columns=list(columns.keys()))
235
+
236
+ return df
237
+
238
+
239
+ @log
240
+ def list_group_transitive_members(group: str | UUID) -> pd.DataFrame:
241
+ """
242
+ Shows a list of the members of a group. This operation is transitive and returns a flat list of all nested members.
243
+
244
+ This is a wrapper function for the following API: `List group transitive members <https://learn.microsoft.com/graph/api/group-list-transitivemembers>`_.
245
+
246
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
247
+
248
+ Parameters
249
+ ----------
250
+ group : str | uuid.UUID
251
+ The group name or ID.
252
+
253
+ Returns
254
+ -------
255
+ pandas.DataFrame
256
+ A pandas dataframe showing a list of the members of a group.
257
+ """
258
+
259
+ group_id = resolve_group_id(group)
260
+
261
+ result = _base_api(
262
+ request=f"groups/{group_id}/transitiveMembers",
263
+ client="graph",
264
+ uses_pagination=True,
265
+ )
266
+
267
+ columns = {
268
+ "Member Id": "string",
269
+ "Organization Id": "string",
270
+ "Description": "string",
271
+ "Member Name": "string",
272
+ "Group Types": "list",
273
+ "Mail": "string",
274
+ "Mail Enabled": "bool",
275
+ "Mail Nickname": "string",
276
+ }
277
+
278
+ df = _create_dataframe(columns=columns)
279
+
280
+ rows = []
281
+ for r in result:
282
+ for v in r.get("value", []):
283
+ rows.append(
284
+ {
285
+ "Member Id": v.get("id"),
286
+ "Organization Id": v.get("organizationId"),
287
+ "Description": v.get("description"),
288
+ "Member Name": v.get("displayName"),
289
+ "Group Types": v.get("groupTypes"),
290
+ "Mail": v.get("mail"),
291
+ "Mail Enabled": v.get("mailEnabled"),
292
+ "Mail Nickname": v.get("mailNickname"),
293
+ }
294
+ )
295
+
296
+ if rows:
297
+ df = pd.DataFrame(rows, columns=list(columns.keys()))
298
+
299
+ return df
300
+
301
+
302
+ @log
303
+ def list_group_owners(group: str | UUID) -> pd.DataFrame:
304
+ """
305
+ Shows a list of the owners of a group.
306
+
307
+ This is a wrapper function for the following API: `List group owners <https://learn.microsoft.com/graph/api/group-list-owners>`_.
308
+
309
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
310
+
311
+ Parameters
312
+ ----------
313
+ group : str | uuid.UUID
314
+ The group name or ID.
315
+
316
+ Returns
317
+ -------
318
+ pandas.DataFrame
319
+ A pandas dataframe showing a list of the owners of a group.
320
+ """
321
+
322
+ group_id = resolve_group_id(group)
323
+
324
+ result = _base_api(
325
+ request=f"groups/{group_id}/owners", client="graph", uses_pagination=True
326
+ )
327
+
328
+ columns = {
329
+ "Owner Id": "string",
330
+ "Owner Name": "string",
331
+ "User Principal Name": "string",
332
+ "Mail": "string",
333
+ "Job Title": "string",
334
+ "Office Location": "string",
335
+ "Mobile Phone": "string",
336
+ "Business Phones": "string",
337
+ "Preferred Language": "string",
338
+ "Given Name": "string",
339
+ "Surname": "string",
340
+ }
341
+
342
+ df = _create_dataframe(columns=columns)
343
+
344
+ rows = []
345
+ for r in result:
346
+ for v in r.get("value", []):
347
+ rows.append(
348
+ {
349
+ "Owner Id": v.get("id"),
350
+ "Owner Name": v.get("displayName"),
351
+ "User Principal Name": v.get("userPrincipalName"),
352
+ "Mail": v.get("mail"),
353
+ "Job Title": v.get("jobTitle"),
354
+ "Office Location": v.get("officeLocation"),
355
+ "Mobile Phone": v.get("mobilePhone"),
356
+ "Business Phones": str(v.get("businessPhones")),
357
+ "Preferred Language": v.get("preferredLanguage"),
358
+ "Given Name": v.get("givenName"),
359
+ "Surname": v.get("surname"),
360
+ }
361
+ )
362
+
363
+ if rows:
364
+ df = pd.DataFrame(rows, columns=list(columns.keys()))
365
+
366
+ return df
367
+
368
+
369
+ @log
370
+ def _base_add_to_group(
371
+ group: str | UUID,
372
+ object: str | UUID,
373
+ object_type: Literal["members", "owners"],
374
+ ):
375
+
376
+ from sempy_labs.graph._users import resolve_user_id
377
+
378
+ object_list = []
379
+
380
+ if isinstance(object, str):
381
+ object = [object]
382
+
383
+ group_id = resolve_group_id(group)
384
+ url = f"groups/{group_id}/{object_type}/$ref"
385
+
386
+ for m in object:
387
+ if _is_valid_uuid(m):
388
+ member_id = m
389
+ else:
390
+ member_id = resolve_user_id(m)
391
+ if object_type == "members":
392
+ object_list.append(
393
+ f"https://graph.microsoft.com/v1.0/directoryObjects/{member_id}"
394
+ )
395
+ else:
396
+ object_list.append(f"https://graph.microsoft.com/v1.0/users/{member_id}")
397
+
398
+ # Must submit one request for each owner. Members can be sent in a single request.
399
+ if object_type == "members":
400
+ payload = {"members@odata.bind": object_list}
401
+
402
+ _base_api(
403
+ request=url,
404
+ client="graph",
405
+ payload=payload,
406
+ method="post",
407
+ status_codes=204,
408
+ )
409
+
410
+ else:
411
+ for o in object_list:
412
+ payload = {"odata.id": o}
413
+ _base_api(
414
+ request=url,
415
+ client="graph",
416
+ payload=payload,
417
+ method="post",
418
+ status_codes=204,
419
+ )
420
+
421
+ print(
422
+ f"{icons.green_dot} The {object} {object_type[:-1]}(s) have been added to the '{group}' group."
423
+ )
424
+
425
+
426
+ @log
427
+ def add_group_members(
428
+ group: str | UUID,
429
+ user: str | UUID | List[str | UUID],
430
+ ):
431
+ """
432
+ Adds a member to a group.
433
+
434
+ This is a wrapper function for the following API: `Add members <https://learn.microsoft.com/graph/api/group-post-members>`_.
435
+
436
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
437
+
438
+ Parameters
439
+ ----------
440
+ group : str | uuid.UUID
441
+ The group name or ID.
442
+ user : str | uuid.UUID
443
+ The user ID or user principal name.
444
+ """
445
+
446
+ _base_add_to_group(group=group, object=user, object_type="members")
447
+
448
+
449
+ @log
450
+ def add_group_owners(
451
+ group: str | UUID,
452
+ user: str | UUID | List[str | UUID],
453
+ ):
454
+ """
455
+ Adds an owner to a group.
456
+
457
+ This is a wrapper function for the following API: `Add owners <https://learn.microsoft.com/graph/api/group-post-owners>`_.
458
+
459
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
460
+
461
+ Parameters
462
+ ----------
463
+ group : str | uuid.UUID
464
+ The group name or ID.
465
+ user : str | uuid.UUID
466
+ The user ID or user principal name.
467
+ """
468
+
469
+ _base_add_to_group(group=group, object=user, object_type="owners")
470
+
471
+
472
+ @log
473
+ def renew_group(group: str | UUID):
474
+ """
475
+ Renews the group.
476
+
477
+ This is a wrapper function for the following API: `Renew group <https://learn.microsoft.com/graph/api/group-post-renew>`_.
478
+
479
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
480
+
481
+ Parameters
482
+ ----------
483
+ group : str | uuid.UUID
484
+ The group name or ID.
485
+ """
486
+
487
+ group_id = resolve_group_id(group)
488
+
489
+ _base_api(
490
+ request=f"groups/{group_id}/renew",
491
+ client="graph",
492
+ method="post",
493
+ status_codes=204,
494
+ )
495
+
496
+ print(f"{icons.green_dot} The '{group}' group has been renewed.")
497
+
498
+
499
+ @log
500
+ def create_group(
501
+ display_name: str,
502
+ description: Optional[str] = None,
503
+ mail_enabled: bool = False,
504
+ security_enabled: bool = True,
505
+ mail_nickname: str = None,
506
+ owners: Optional[str | UUID | List[str | UUID]] = None,
507
+ members: Optional[str | UUID | List[str | UUID]] = None,
508
+ ):
509
+ """
510
+ Creates a new group.
511
+
512
+ This is a wrapper function for the following API: `Create group <https://learn.microsoft.com/graph/api/group-post-groups>`_.
513
+
514
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
515
+
516
+ Parameters
517
+ ----------
518
+ display_name : str
519
+ The name of the group.
520
+ description : str, optional
521
+ The description of the group.
522
+ mail_enabled : bool, default=False
523
+ Whether the group is mail-enabled.
524
+ security_enabled : bool, default=True
525
+ Whether the group is security-enabled.
526
+ mail_nickname : str, default=None
527
+ The mail alias for the group.
528
+ owners : str | uuid.UUID | List[str | uuid.UUID], default=None
529
+ The owners of the group.
530
+ members : str | uuid.UUID | List[str | uuid.UUID], default=None
531
+ The members of the group.
532
+ """
533
+ from sempy_labs.graph._users import resolve_user_id
534
+
535
+ payload = {
536
+ "displayName": display_name,
537
+ "description": description,
538
+ "mailEnabled": mail_enabled,
539
+ "securityEnabled": security_enabled,
540
+ "mailNickname": mail_nickname,
541
+ }
542
+
543
+ if owners:
544
+ if isinstance(owners, str):
545
+ owners = [owners]
546
+ user_list = []
547
+ for o in owners:
548
+ user_id = resolve_user_id(o)
549
+ user_list.append(f"https://graph.microsoft.com/v1.0/users/{user_id}")
550
+ payload["owners@odata.bind"] = user_list
551
+ if members:
552
+ if isinstance(members, str):
553
+ members = [members]
554
+ user_list = []
555
+ for m in members:
556
+ user_id = resolve_user_id(m)
557
+ user_list.append(f"https://graph.microsoft.com/v1.0/users/{user_id}")
558
+ payload["members@odata.bind"] = user_list
559
+
560
+ _base_api(
561
+ request="groups",
562
+ client="graph",
563
+ payload=payload,
564
+ method="post",
565
+ status_codes=201,
566
+ )
567
+
568
+ print(f"{icons.green_dot} The '{display_name}' group has been created.")
569
+
570
+
571
+ @log
572
+ def delete_group(group: str | UUID):
573
+ """
574
+ Deletes a group.
575
+
576
+ This is a wrapper function for the following API: `Delete group <https://learn.microsoft.com/graph/api/group-delete>`_.
577
+
578
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
579
+
580
+ Parameters
581
+ ----------
582
+ group : str | uuid.UUID
583
+ The group name or ID.
584
+ """
585
+
586
+ group_id = resolve_group_id(group)
587
+
588
+ _base_api(
589
+ request=f"groups/{group_id}",
590
+ client="graph",
591
+ status_codes=204,
592
+ method="delete",
593
+ )
594
+
595
+ print(f"{icons.green_dot} The '{group}' group has been deleted successfully.")
596
+
597
+
598
+ @log
599
+ def update_group(
600
+ group: str | UUID,
601
+ display_name: Optional[str] = None,
602
+ mail_nickname: Optional[str] = None,
603
+ description: Optional[str] = None,
604
+ security_enabled: Optional[bool] = None,
605
+ ):
606
+ """
607
+ Updates a group's properties.
608
+
609
+ This is a wrapper function for the following API: `Update group <https://learn.microsoft.com/en-us/graph/api/group-update>`_.
610
+
611
+ Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
612
+
613
+ Parameters
614
+ ----------
615
+ group : str | uuid.UUID
616
+ The group name or ID.
617
+ display_name : str, default=None
618
+ The new display name for the group.
619
+ mail_nickname : str, default=None
620
+ The new mail nickname for the group.
621
+ description : str, default=None
622
+ The new description for the group.
623
+ security_enabled : bool, default=None
624
+ Whether the group is security-enabled.
625
+ """
626
+
627
+ group_id = resolve_group_id(group)
628
+
629
+ payload = {}
630
+ if display_name:
631
+ payload["displayName"] = display_name
632
+ if mail_nickname:
633
+ payload["mailNickname"] = mail_nickname
634
+ if description:
635
+ payload["description"] = description
636
+ if security_enabled is not None and isinstance(security_enabled, bool):
637
+ payload["securityEnabled"] = security_enabled
638
+
639
+ if not payload:
640
+ print(f"{icons.info} No properties to update.")
641
+ return
642
+
643
+ _base_api(
644
+ request=f"groups/{group_id}",
645
+ client="graph",
646
+ status_codes=204,
647
+ payload=payload,
648
+ method="patch",
649
+ )
650
+
651
+ print(f"{icons.green_dot} The '{group}' group has been updated successfully.")