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,140 @@
1
+ from sempy_labs._helper_functions import (
2
+ _base_api,
3
+ _create_dataframe,
4
+ _update_dataframe_datatypes,
5
+ )
6
+ from uuid import UUID
7
+ import pandas as pd
8
+ from sempy._utils._log import log
9
+
10
+
11
+ @log
12
+ def list_access_entities(
13
+ user_email_address: str,
14
+ ) -> pd.DataFrame:
15
+ """
16
+ Shows a list of permission details for Fabric and Power BI items the specified user can access.
17
+
18
+ This is a wrapper function for the following API: `Users - List Access Entities <https://learn.microsoft.com/rest/api/fabric/admin/users/list-access-entities>`_.
19
+
20
+ Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
21
+
22
+ Parameters
23
+ ----------
24
+ user_email_address : str
25
+ The user's email address.
26
+
27
+ Returns
28
+ -------
29
+ pandas.DataFrame
30
+ A pandas dataframe showing a list of permission details for Fabric and Power BI items the specified user can access.
31
+ """
32
+
33
+ columns = {
34
+ "Item Id": "string",
35
+ "Item Name": "string",
36
+ "Item Type": "string",
37
+ "Permissions": "string",
38
+ "Additional Permissions": "string",
39
+ }
40
+ df = _create_dataframe(columns=columns)
41
+
42
+ responses = _base_api(
43
+ request=f"/v1/admin/users/{user_email_address}/access",
44
+ client="fabric_sp",
45
+ uses_pagination=True,
46
+ )
47
+
48
+ rows = []
49
+ for r in responses:
50
+ for v in r.get("accessEntities", []):
51
+ rows.append(
52
+ {
53
+ "Item Id": v.get("id"),
54
+ "Item Name": v.get("displayName"),
55
+ "Item Type": v.get("itemAccessDetails", {}).get("type"),
56
+ "Permissions": v.get("itemAccessDetails", {}).get("permissions"),
57
+ "Additional Permissions": v.get("itemAccessDetails", {}).get(
58
+ "additionalPermissions"
59
+ ),
60
+ }
61
+ )
62
+
63
+ if rows:
64
+ df = pd.DataFrame(rows, columns=list(columns.keys()))
65
+
66
+ return df
67
+
68
+
69
+ @log
70
+ def list_user_subscriptions(user: str | UUID) -> pd.DataFrame:
71
+ """
72
+ Shows a list of subscriptions for the specified user. This is a preview API call.
73
+
74
+ This is a wrapper function for the following API: `Admin - Users GetUserSubscriptionsAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/users-get-user-subscriptions-as-admin>`_.
75
+
76
+ Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
77
+
78
+ Parameters
79
+ ----------
80
+ user : str | uuid.UUID
81
+ The graph ID or user principal name (UPN) of the user.
82
+
83
+ Returns
84
+ -------
85
+ pandas.DataFrame
86
+ A pandas dataframe showing a list of subscriptions for the specified user. This is a preview API call.
87
+ """
88
+
89
+ columns = {
90
+ "Subscription Id": "string",
91
+ "Title": "string",
92
+ "Artifact Id": "string",
93
+ "Artifact Name": "string",
94
+ "Sub Artifact Name": "string",
95
+ "Artifact Type": "string",
96
+ "Is Enabled": "bool",
97
+ "Frequency": "string",
98
+ "Start Date": "datetime",
99
+ "End Date": "string",
100
+ "Link To Content": "bool",
101
+ "Preview Image": "bool",
102
+ "Attachment Format": "string",
103
+ "Users": "string",
104
+ }
105
+
106
+ df = _create_dataframe(columns=columns)
107
+
108
+ responses = _base_api(
109
+ request=f"/v1.0/myorg/admin/users/{user}/subscriptions",
110
+ client="fabric_sp",
111
+ uses_pagination=True,
112
+ )
113
+
114
+ rows = []
115
+ for r in responses:
116
+ for v in r.get("subscriptionEntities", []):
117
+ rows.append(
118
+ {
119
+ "Subscription Id": v.get("id"),
120
+ "Title": v.get("title"),
121
+ "Artifact Id": v.get("artifactId"),
122
+ "Artifact Name": v.get("artifactDisplayName"),
123
+ "Sub Artifact Name": v.get("subArtifactDisplayName"),
124
+ "Artifact Type": v.get("artifactType"),
125
+ "Is Enabled": v.get("isEnabled"),
126
+ "Frequency": v.get("frequency"),
127
+ "Start Date": v.get("startDate"),
128
+ "End Date": v.get("endDate"),
129
+ "Link To Content": v.get("linkToContent"),
130
+ "Preview Image": v.get("previewImage"),
131
+ "Attachment Format": v.get("attachmentFormat"),
132
+ "Users": str(v.get("users")),
133
+ }
134
+ )
135
+
136
+ if rows:
137
+ df = pd.DataFrame(rows, columns=list(columns.keys()))
138
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
139
+
140
+ return df
@@ -0,0 +1,236 @@
1
+ from sempy_labs._helper_functions import (
2
+ _base_api,
3
+ _build_url,
4
+ _encode_user,
5
+ _update_dataframe_datatypes,
6
+ _create_dataframe,
7
+ )
8
+
9
+ from uuid import UUID
10
+ from typing import Optional
11
+ from sempy_labs.admin._basic_functions import (
12
+ _resolve_workspace_name_and_id,
13
+ )
14
+ import sempy_labs._icons as icons
15
+ import pandas as pd
16
+ from sempy._utils._log import log
17
+
18
+
19
+ @log
20
+ def add_user_to_workspace(
21
+ user: str | UUID,
22
+ role: str = "Member",
23
+ principal_type: str = "User",
24
+ workspace: Optional[str | UUID] = None,
25
+ ):
26
+ """
27
+ Grants user permissions to the specified workspace.
28
+
29
+ This is a wrapper function for the following API: `Admin - Groups AddUserAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-add-user-as-admin>`_.
30
+
31
+ Parameters
32
+ ----------
33
+ user : str | uuid.UUID
34
+ The user identifier or email address. For service principals and groups you must use the user identifier.
35
+ role : str, default="Member"
36
+ The role of the user in the workspace. Options are: 'Admin', 'Contributor', 'Member', 'None', 'Viewer'.
37
+ principal_type : str, default="User"
38
+ The principal type of the user. Options are: 'App', 'Group', 'None', 'User'.
39
+ workspace : str | uuid.UUID, default=None
40
+ The Fabric workspace name or ID.
41
+ Defaults to None which resolves to the workspace of the attached lakehouse
42
+ or if no lakehouse attached, resolves to the workspace of the notebook.
43
+ """
44
+
45
+ (workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
46
+
47
+ # Validation
48
+ role = role.capitalize()
49
+ roles = ["Admin", "Contributor", "Member", "None", "Viewer"]
50
+ if role not in roles:
51
+ raise ValueError(f"{icons.red_dot} Invalid role. Please choose from {roles}")
52
+ principal_types = ["App", "Group", "None", "User"]
53
+ if principal_type not in principal_types:
54
+ raise ValueError(
55
+ f"{icons.red_dot} Invalid principal type. Please choose from {principal_types}"
56
+ )
57
+
58
+ user = _encode_user(user)
59
+
60
+ payload = {
61
+ "identifier": user, # identifier or emailAddress?
62
+ "principalType": principal_type,
63
+ "groupUserAccessRight": role,
64
+ }
65
+
66
+ _base_api(
67
+ request=f"/v1.0/myorg/admin/groups/{workspace_id}/users",
68
+ method="post",
69
+ payload=payload,
70
+ )
71
+
72
+ print(
73
+ f"{icons.green_dot} The '{user}' user has been added with '{role.lower()}' permissions to the '{workspace_name}' workspace."
74
+ )
75
+
76
+
77
+ @log
78
+ def delete_user_from_workspace(
79
+ user: str | UUID,
80
+ workspace: Optional[str | UUID] = None,
81
+ is_group: Optional[bool] = None,
82
+ profile_id: Optional[str] = None,
83
+ ):
84
+ """
85
+ Removes user permissions from the specified workspace.
86
+
87
+ This is a wrapper function for the following API: `Admin - Groups DeleteUserAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-delete-user-as-admin>`_.
88
+
89
+ Parameters
90
+ ----------
91
+ user : str | uuid.UUID
92
+ The user identifier or email address. For service principals and groups you must use the user identifier.
93
+ workspace : str | uuid.UUID, default=None
94
+ The Fabric workspace name or ID.
95
+ Defaults to None which resolves to the workspace of the attached lakehouse
96
+ or if no lakehouse attached, resolves to the workspace of the notebook.
97
+ is_group : bool, default=None
98
+ Whether a given user is a group or not. This parameter is required when user to delete is group.
99
+ profile_id : str, default=None
100
+ The service principal profile ID to delete.
101
+ """
102
+
103
+ (workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
104
+
105
+ user = _encode_user(user)
106
+ url = f"/v1.0/myorg/admin/groups/{workspace_id}/users/{user}"
107
+
108
+ params = {}
109
+ if profile_id is not None:
110
+ params["profileId"] = profile_id
111
+ if is_group is not None:
112
+ params["isGroup"] = is_group
113
+
114
+ url = _build_url(url, params)
115
+
116
+ _base_api(
117
+ request=url,
118
+ method="delete",
119
+ )
120
+
121
+ print(
122
+ f"{icons.green_dot} The '{user}' user has been removed from the '{workspace_name}' workspace."
123
+ )
124
+
125
+
126
+ @log
127
+ def restore_deleted_workspace(workspace_id: UUID, name: str, email_address: str):
128
+ """
129
+ Restores a deleted workspace.
130
+
131
+ This is a wrapper function for the following API: `Admin - Groups RestoreDeletedGroupAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-restore-deleted-group-as-admin>`_.
132
+
133
+ Parameters
134
+ ----------
135
+ workspace_id : uuid.UUID
136
+ The ID of the workspace to restore.
137
+ name : str
138
+ The name of the group to be restored
139
+ email_address : str
140
+ The email address of the owner of the group to be restored
141
+ """
142
+
143
+ payload = {
144
+ "name": name,
145
+ "emailAddress": email_address,
146
+ }
147
+
148
+ _base_api(
149
+ request=f"/v1.0/myorg/admin/groups/{workspace_id}/restore",
150
+ method="post",
151
+ payload=payload,
152
+ )
153
+
154
+ print(
155
+ f"{icons.green_dot} The '{workspace_id}' workspace has been restored as '{name}'."
156
+ )
157
+
158
+
159
+ @log
160
+ def list_orphaned_workspaces(top: int = 100) -> pd.DataFrame:
161
+ """
162
+ Shows a list of orphaned workspaces (those with no users or no admins).
163
+
164
+ This is a wrapper function for the following API:
165
+ `Admin - Groups ListGroupsAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-get-groups-as-admin>`_.
166
+
167
+ Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
168
+
169
+ Parameters
170
+ ----------
171
+ top : int, default=100
172
+ The maximum number of results to return.
173
+
174
+ Returns
175
+ -------
176
+ pandas.DataFrame
177
+ A pandas dataframe showing a list of orphaned workspaces.
178
+ """
179
+
180
+ # column structure with proper data types
181
+ columns = {
182
+ "Workspace Name": "string",
183
+ "Workspace Id": "string",
184
+ "Type": "string",
185
+ "State": "string",
186
+ "Is Read Only": "bool",
187
+ "Is On Dedicated Capacity": "bool",
188
+ "Capacity Migration Status": "string",
189
+ "Has Workspace Level Settings": "bool",
190
+ "Users": "list",
191
+ }
192
+
193
+ df = _create_dataframe(columns=columns)
194
+
195
+ url = (
196
+ "/v1.0/myorg/admin/groups?"
197
+ "$expand=users&"
198
+ "$filter=(not users/any()) or "
199
+ "(not users/any(u: u/groupUserAccessRight eq Microsoft.PowerBI.ServiceContracts.Api.GroupUserAccessRight'Admin'))&"
200
+ f"$top={top}"
201
+ )
202
+
203
+ response = _base_api(request=url, client="fabric_sp")
204
+ values = response.json().get("value", [])
205
+ df_raw = pd.json_normalize(values)
206
+
207
+ # friendly names and reorder
208
+ if not df_raw.empty:
209
+ df_raw = df_raw.rename(
210
+ columns={
211
+ "name": "Workspace Name",
212
+ "id": "Workspace Id",
213
+ "type": "Type",
214
+ "state": "State",
215
+ "isReadOnly": "Is Read Only",
216
+ "isOnDedicatedCapacity": "Is On Dedicated Capacity",
217
+ "capacityMigrationStatus": "Capacity Migration Status",
218
+ "hasWorkspaceLevelSettings ": "Has Workspace Level Settings", # Note the space in original
219
+ "users": "Users",
220
+ }
221
+ )
222
+
223
+ df = df_raw[list(columns.keys())].copy()
224
+
225
+ # Convert empty lists to a more readable format for Users column
226
+ if "Users" in df.columns:
227
+ df["Users"] = df["Users"].apply(
228
+ lambda x: x if (x is not None and len(x) > 0) else []
229
+ )
230
+ else:
231
+ df = _create_dataframe(columns=columns)
232
+
233
+ # proper data types
234
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
235
+
236
+ return df
@@ -0,0 +1,23 @@
1
+ from ._items import (
2
+ list_deployment_pipeline_operations,
3
+ list_deployment_pipeline_role_assignments,
4
+ list_deployment_pipeline_stage_items,
5
+ list_deployment_pipeline_stages,
6
+ list_deployment_pipelines,
7
+ unassign_workspace_from_stage,
8
+ assign_workspace_to_stage,
9
+ delete_deployment_pipeline,
10
+ deploy_stage_content,
11
+ )
12
+
13
+ __all__ = [
14
+ "list_deployment_pipeline_operations",
15
+ "list_deployment_pipeline_role_assignments",
16
+ "list_deployment_pipeline_stage_items",
17
+ "list_deployment_pipeline_stages",
18
+ "list_deployment_pipelines",
19
+ "unassign_workspace_from_stage",
20
+ "assign_workspace_to_stage",
21
+ "delete_deployment_pipeline",
22
+ "deploy_stage_content",
23
+ ]