semantic-link-labs 0.7.3__py3-none-any.whl → 0.8.0__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.
- {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/METADATA +19 -4
- {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/RECORD +75 -50
- {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/WHEEL +1 -1
- sempy_labs/__init__.py +109 -31
- sempy_labs/_bpa_translation/{_translations_am-ET.po → _model/_translations_am-ET.po} +22 -0
- sempy_labs/_bpa_translation/{_translations_ar-AE.po → _model/_translations_ar-AE.po} +24 -0
- sempy_labs/_bpa_translation/_model/_translations_bg-BG.po +938 -0
- sempy_labs/_bpa_translation/_model/_translations_ca-ES.po +934 -0
- sempy_labs/_bpa_translation/{_translations_cs-CZ.po → _model/_translations_cs-CZ.po} +179 -157
- sempy_labs/_bpa_translation/{_translations_da-DK.po → _model/_translations_da-DK.po} +24 -0
- sempy_labs/_bpa_translation/{_translations_de-DE.po → _model/_translations_de-DE.po} +77 -52
- sempy_labs/_bpa_translation/{_translations_el-GR.po → _model/_translations_el-GR.po} +25 -0
- sempy_labs/_bpa_translation/{_translations_es-ES.po → _model/_translations_es-ES.po} +67 -43
- sempy_labs/_bpa_translation/{_translations_fa-IR.po → _model/_translations_fa-IR.po} +24 -0
- sempy_labs/_bpa_translation/_model/_translations_fi-FI.po +915 -0
- sempy_labs/_bpa_translation/{_translations_fr-FR.po → _model/_translations_fr-FR.po} +83 -57
- sempy_labs/_bpa_translation/{_translations_ga-IE.po → _model/_translations_ga-IE.po} +25 -0
- sempy_labs/_bpa_translation/{_translations_he-IL.po → _model/_translations_he-IL.po} +23 -0
- sempy_labs/_bpa_translation/{_translations_hi-IN.po → _model/_translations_hi-IN.po} +24 -0
- sempy_labs/_bpa_translation/{_translations_hu-HU.po → _model/_translations_hu-HU.po} +25 -0
- sempy_labs/_bpa_translation/_model/_translations_id-ID.po +918 -0
- sempy_labs/_bpa_translation/{_translations_is-IS.po → _model/_translations_is-IS.po} +25 -0
- sempy_labs/_bpa_translation/{_translations_it-IT.po → _model/_translations_it-IT.po} +25 -0
- sempy_labs/_bpa_translation/{_translations_ja-JP.po → _model/_translations_ja-JP.po} +21 -0
- sempy_labs/_bpa_translation/_model/_translations_ko-KR.po +823 -0
- sempy_labs/_bpa_translation/_model/_translations_mt-MT.po +937 -0
- sempy_labs/_bpa_translation/{_translations_nl-NL.po → _model/_translations_nl-NL.po} +80 -56
- sempy_labs/_bpa_translation/{_translations_pl-PL.po → _model/_translations_pl-PL.po} +101 -76
- sempy_labs/_bpa_translation/{_translations_pt-BR.po → _model/_translations_pt-BR.po} +25 -0
- sempy_labs/_bpa_translation/{_translations_pt-PT.po → _model/_translations_pt-PT.po} +25 -0
- sempy_labs/_bpa_translation/_model/_translations_ro-RO.po +939 -0
- sempy_labs/_bpa_translation/{_translations_ru-RU.po → _model/_translations_ru-RU.po} +25 -0
- sempy_labs/_bpa_translation/_model/_translations_sk-SK.po +925 -0
- sempy_labs/_bpa_translation/_model/_translations_sl-SL.po +922 -0
- sempy_labs/_bpa_translation/{_translations_ta-IN.po → _model/_translations_ta-IN.po} +26 -0
- sempy_labs/_bpa_translation/{_translations_te-IN.po → _model/_translations_te-IN.po} +24 -0
- sempy_labs/_bpa_translation/{_translations_th-TH.po → _model/_translations_th-TH.po} +24 -0
- sempy_labs/_bpa_translation/_model/_translations_tr-TR.po +925 -0
- sempy_labs/_bpa_translation/_model/_translations_uk-UA.po +933 -0
- sempy_labs/_bpa_translation/{_translations_zh-CN.po → _model/_translations_zh-CN.po} +116 -97
- sempy_labs/_bpa_translation/{_translations_zu-ZA.po → _model/_translations_zu-ZA.po} +25 -0
- sempy_labs/_capacities.py +577 -0
- sempy_labs/_capacity_migration.py +624 -0
- sempy_labs/_clear_cache.py +8 -8
- sempy_labs/_connections.py +140 -0
- sempy_labs/_environments.py +156 -0
- sempy_labs/_git.py +20 -21
- sempy_labs/_helper_functions.py +151 -10
- sempy_labs/_icons.py +62 -0
- sempy_labs/_list_functions.py +232 -887
- sempy_labs/_model_bpa.py +8 -32
- sempy_labs/_notebooks.py +143 -0
- sempy_labs/_query_scale_out.py +30 -8
- sempy_labs/_spark.py +460 -0
- sempy_labs/_sql.py +88 -19
- sempy_labs/_translations.py +3 -0
- sempy_labs/_vertipaq.py +162 -99
- sempy_labs/_workspaces.py +294 -0
- sempy_labs/admin/__init__.py +53 -0
- sempy_labs/admin/_basic_functions.py +806 -0
- sempy_labs/admin/_domains.py +411 -0
- sempy_labs/directlake/_directlake_schema_sync.py +1 -2
- sempy_labs/directlake/_generate_shared_expression.py +11 -14
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +14 -24
- sempy_labs/report/__init__.py +9 -6
- sempy_labs/report/_report_bpa.py +359 -0
- sempy_labs/report/_report_bpa_rules.py +113 -0
- sempy_labs/report/_report_helper.py +254 -0
- sempy_labs/report/_report_list_functions.py +95 -0
- sempy_labs/report/_report_rebind.py +0 -4
- sempy_labs/report/_reportwrapper.py +2039 -0
- sempy_labs/tom/_model.py +83 -5
- {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/top_level.txt +0 -0
- /sempy_labs/_bpa_translation/{_translations_sv-SE.po → _model/_translations_sv-SE.po} +0 -0
sempy_labs/_list_functions.py
CHANGED
|
@@ -4,15 +4,13 @@ from sempy_labs._helper_functions import (
|
|
|
4
4
|
create_relationship_name,
|
|
5
5
|
resolve_lakehouse_id,
|
|
6
6
|
resolve_dataset_id,
|
|
7
|
-
_decode_b64,
|
|
8
7
|
pagination,
|
|
9
8
|
lro,
|
|
10
9
|
resolve_item_type,
|
|
10
|
+
format_dax_object_name,
|
|
11
|
+
pagination,
|
|
11
12
|
)
|
|
12
13
|
import pandas as pd
|
|
13
|
-
import base64
|
|
14
|
-
import requests
|
|
15
|
-
from pyspark.sql import SparkSession
|
|
16
14
|
from typing import Optional
|
|
17
15
|
import sempy_labs._icons as icons
|
|
18
16
|
from sempy.fabric.exceptions import FabricHTTPException
|
|
@@ -169,10 +167,19 @@ def list_tables(
|
|
|
169
167
|
dataset=dataset,
|
|
170
168
|
workspace=workspace,
|
|
171
169
|
dax_string="""
|
|
172
|
-
SELECT [DIMENSION_NAME],[
|
|
170
|
+
SELECT [DIMENSION_NAME],[ROWS_COUNT] FROM $SYSTEM.DISCOVER_STORAGE_TABLES
|
|
171
|
+
WHERE RIGHT ( LEFT ( TABLE_ID, 2 ), 1 ) <> '$'
|
|
173
172
|
""",
|
|
174
173
|
)
|
|
175
174
|
|
|
175
|
+
model_size = (
|
|
176
|
+
dict_sum.sum()
|
|
177
|
+
+ data_sum.sum()
|
|
178
|
+
+ hier_sum.sum()
|
|
179
|
+
+ rel_sum.sum()
|
|
180
|
+
+ uh_sum.sum()
|
|
181
|
+
)
|
|
182
|
+
|
|
176
183
|
rows = []
|
|
177
184
|
for t in tom.model.Tables:
|
|
178
185
|
t_name = t.Name
|
|
@@ -209,9 +216,7 @@ def list_tables(
|
|
|
209
216
|
new_data.update(
|
|
210
217
|
{
|
|
211
218
|
"Row Count": (
|
|
212
|
-
rc[rc["DIMENSION_NAME"] == t_name][
|
|
213
|
-
"DIMENSION_CARDINALITY"
|
|
214
|
-
].iloc[0]
|
|
219
|
+
rc[rc["DIMENSION_NAME"] == t_name]["ROWS_COUNT"].iloc[0]
|
|
215
220
|
if not rc.empty
|
|
216
221
|
else 0
|
|
217
222
|
),
|
|
@@ -221,24 +226,33 @@ def list_tables(
|
|
|
221
226
|
"Hierarchy Size": h_size,
|
|
222
227
|
"Relationship Size": r_size,
|
|
223
228
|
"User Hierarchy Size": u_size,
|
|
229
|
+
"Partitions": int(len(t.Partitions)),
|
|
230
|
+
"Columns": sum(
|
|
231
|
+
1 for c in t.Columns if str(c.Type) != "RowNumber"
|
|
232
|
+
),
|
|
233
|
+
"% DB": round((total_size / model_size) * 100, 2),
|
|
224
234
|
}
|
|
225
235
|
)
|
|
226
236
|
|
|
227
237
|
rows.append(new_data)
|
|
228
238
|
|
|
229
|
-
int_cols = [
|
|
230
|
-
"Row Count",
|
|
231
|
-
"Total Size",
|
|
232
|
-
"Dictionary Size",
|
|
233
|
-
"Data Size",
|
|
234
|
-
"Hierarchy Size",
|
|
235
|
-
"Relationship Size",
|
|
236
|
-
"User Hierarchy Size",
|
|
237
|
-
]
|
|
238
|
-
df[int_cols] = df[int_cols].astype(int)
|
|
239
|
-
|
|
240
239
|
df = pd.DataFrame(rows)
|
|
241
240
|
|
|
241
|
+
if extended:
|
|
242
|
+
int_cols = [
|
|
243
|
+
"Row Count",
|
|
244
|
+
"Total Size",
|
|
245
|
+
"Dictionary Size",
|
|
246
|
+
"Data Size",
|
|
247
|
+
"Hierarchy Size",
|
|
248
|
+
"Relationship Size",
|
|
249
|
+
"User Hierarchy Size",
|
|
250
|
+
"Partitions",
|
|
251
|
+
"Columns",
|
|
252
|
+
]
|
|
253
|
+
df[int_cols] = df[int_cols].astype(int)
|
|
254
|
+
df["% DB"] = df["% DB"].astype(float)
|
|
255
|
+
|
|
242
256
|
return df
|
|
243
257
|
|
|
244
258
|
|
|
@@ -505,6 +519,7 @@ def list_columns(
|
|
|
505
519
|
from sempy_labs.directlake._get_directlake_lakehouse import (
|
|
506
520
|
get_direct_lake_lakehouse,
|
|
507
521
|
)
|
|
522
|
+
from pyspark.sql import SparkSession
|
|
508
523
|
|
|
509
524
|
workspace = fabric.resolve_workspace_name(workspace)
|
|
510
525
|
|
|
@@ -1274,6 +1289,8 @@ def list_relationships(
|
|
|
1274
1289
|
workspace = fabric.resolve_workspace_name(workspace)
|
|
1275
1290
|
|
|
1276
1291
|
dfR = fabric.list_relationships(dataset=dataset, workspace=workspace)
|
|
1292
|
+
dfR["From Object"] = format_dax_object_name(dfR["From Table"], dfR["From Column"])
|
|
1293
|
+
dfR["To Object"] = format_dax_object_name(dfR["To Table"], dfR["To Column"])
|
|
1277
1294
|
|
|
1278
1295
|
if extended:
|
|
1279
1296
|
# Used to map the Relationship IDs
|
|
@@ -1393,48 +1410,6 @@ def list_kpis(dataset: str, workspace: Optional[str] = None) -> pd.DataFrame:
|
|
|
1393
1410
|
return df
|
|
1394
1411
|
|
|
1395
1412
|
|
|
1396
|
-
def list_workspace_role_assignments(workspace: Optional[str] = None) -> pd.DataFrame:
|
|
1397
|
-
"""
|
|
1398
|
-
Shows the members of a given workspace.
|
|
1399
|
-
|
|
1400
|
-
Parameters
|
|
1401
|
-
----------
|
|
1402
|
-
workspace : str, default=None
|
|
1403
|
-
The Fabric workspace name.
|
|
1404
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
1405
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1406
|
-
|
|
1407
|
-
Returns
|
|
1408
|
-
-------
|
|
1409
|
-
pandas.DataFrame
|
|
1410
|
-
A pandas dataframe showing the members of a given workspace and their roles.
|
|
1411
|
-
"""
|
|
1412
|
-
|
|
1413
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
1414
|
-
|
|
1415
|
-
df = pd.DataFrame(columns=["User Name", "User Email", "Role Name", "Type"])
|
|
1416
|
-
|
|
1417
|
-
client = fabric.FabricRestClient()
|
|
1418
|
-
response = client.get(f"/v1/workspaces/{workspace_id}/roleAssignments")
|
|
1419
|
-
if response.status_code != 200:
|
|
1420
|
-
raise FabricHTTPException(response)
|
|
1421
|
-
|
|
1422
|
-
responses = pagination(client, response)
|
|
1423
|
-
|
|
1424
|
-
for r in responses:
|
|
1425
|
-
for i in r.get("value", []):
|
|
1426
|
-
principal = i.get("principal", {})
|
|
1427
|
-
new_data = {
|
|
1428
|
-
"User Name": principal.get("displayName"),
|
|
1429
|
-
"Role Name": i.get("role"),
|
|
1430
|
-
"Type": principal.get("type"),
|
|
1431
|
-
"User Email": principal.get("userDetails", {}).get("userPrincipalName"),
|
|
1432
|
-
}
|
|
1433
|
-
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
1434
|
-
|
|
1435
|
-
return df
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
1413
|
def list_semantic_model_objects(
|
|
1439
1414
|
dataset: str, workspace: Optional[str] = None
|
|
1440
1415
|
) -> pd.DataFrame:
|
|
@@ -1709,933 +1684,303 @@ def list_shortcuts(
|
|
|
1709
1684
|
return df
|
|
1710
1685
|
|
|
1711
1686
|
|
|
1712
|
-
def
|
|
1687
|
+
def list_capacities() -> pd.DataFrame:
|
|
1713
1688
|
"""
|
|
1714
|
-
|
|
1689
|
+
Shows the capacities and their properties.
|
|
1715
1690
|
|
|
1716
1691
|
Parameters
|
|
1717
1692
|
----------
|
|
1718
|
-
workspace : str, default=None
|
|
1719
|
-
The name of the Fabric workspace.
|
|
1720
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
1721
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1722
1693
|
|
|
1723
1694
|
Returns
|
|
1724
1695
|
-------
|
|
1725
1696
|
pandas.DataFrame
|
|
1726
|
-
A pandas dataframe showing
|
|
1697
|
+
A pandas dataframe showing the capacities and their properties
|
|
1727
1698
|
"""
|
|
1728
1699
|
|
|
1729
|
-
# https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/list-workspace-custom-pools
|
|
1730
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
1731
|
-
|
|
1732
1700
|
df = pd.DataFrame(
|
|
1733
|
-
columns=[
|
|
1734
|
-
"Custom Pool ID",
|
|
1735
|
-
"Custom Pool Name",
|
|
1736
|
-
"Type",
|
|
1737
|
-
"Node Family",
|
|
1738
|
-
"Node Size",
|
|
1739
|
-
"Auto Scale Enabled",
|
|
1740
|
-
"Auto Scale Min Node Count",
|
|
1741
|
-
"Auto Scale Max Node Count",
|
|
1742
|
-
"Dynamic Executor Allocation Enabled",
|
|
1743
|
-
"Dynamic Executor Allocation Min Executors",
|
|
1744
|
-
"Dynamic Executor Allocation Max Executors",
|
|
1745
|
-
]
|
|
1701
|
+
columns=["Id", "Display Name", "Sku", "Region", "State", "Admins"]
|
|
1746
1702
|
)
|
|
1747
1703
|
|
|
1748
|
-
client = fabric.
|
|
1749
|
-
response = client.get(
|
|
1704
|
+
client = fabric.PowerBIRestClient()
|
|
1705
|
+
response = client.get("/v1.0/myorg/capacities")
|
|
1750
1706
|
if response.status_code != 200:
|
|
1751
1707
|
raise FabricHTTPException(response)
|
|
1752
1708
|
|
|
1753
|
-
for i in response.json()
|
|
1754
|
-
|
|
1755
|
-
aScale = i.get("autoScale", {})
|
|
1756
|
-
d = i.get("dynamicExecutorAllocation", {})
|
|
1757
|
-
|
|
1709
|
+
for i in response.json().get("value", []):
|
|
1758
1710
|
new_data = {
|
|
1759
|
-
"
|
|
1760
|
-
"
|
|
1761
|
-
"
|
|
1762
|
-
"
|
|
1763
|
-
"
|
|
1764
|
-
"
|
|
1765
|
-
"Auto Scale Min Node Count": aScale.get("minNodeCount"),
|
|
1766
|
-
"Auto Scale Max Node Count": aScale.get("maxNodeCount"),
|
|
1767
|
-
"Dynamic Executor Allocation Enabled": d.get("enabled"),
|
|
1768
|
-
"Dynamic Executor Allocation Min Executors": d.get("minExecutors"),
|
|
1769
|
-
"Dynamic Executor Allocation Max Executors": d.get("maxExecutors"),
|
|
1711
|
+
"Id": i.get("id").lower(),
|
|
1712
|
+
"Display Name": i.get("displayName"),
|
|
1713
|
+
"Sku": i.get("sku"),
|
|
1714
|
+
"Region": i.get("region"),
|
|
1715
|
+
"State": i.get("state"),
|
|
1716
|
+
"Admins": [i.get("admins", [])],
|
|
1770
1717
|
}
|
|
1771
1718
|
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
1772
1719
|
|
|
1773
|
-
bool_cols = ["Auto Scale Enabled", "Dynamic Executor Allocation Enabled"]
|
|
1774
|
-
int_cols = [
|
|
1775
|
-
"Auto Scale Min Node Count",
|
|
1776
|
-
"Auto Scale Max Node Count",
|
|
1777
|
-
"Dynamic Executor Allocation Enabled",
|
|
1778
|
-
"Dynamic Executor Allocation Min Executors",
|
|
1779
|
-
"Dynamic Executor Allocation Max Executors",
|
|
1780
|
-
]
|
|
1781
|
-
|
|
1782
|
-
df[bool_cols] = df[bool_cols].astype(bool)
|
|
1783
|
-
df[int_cols] = df[int_cols].astype(int)
|
|
1784
|
-
|
|
1785
1720
|
return df
|
|
1786
1721
|
|
|
1787
1722
|
|
|
1788
|
-
def
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
min_node_count: int,
|
|
1792
|
-
max_node_count: int,
|
|
1793
|
-
min_executors: int,
|
|
1794
|
-
max_executors: int,
|
|
1795
|
-
node_family: Optional[str] = "MemoryOptimized",
|
|
1796
|
-
auto_scale_enabled: Optional[bool] = True,
|
|
1797
|
-
dynamic_executor_allocation_enabled: Optional[bool] = True,
|
|
1798
|
-
workspace: Optional[str] = None,
|
|
1799
|
-
):
|
|
1800
|
-
"""
|
|
1801
|
-
Creates a `custom pool <https://learn.microsoft.com/fabric/data-engineering/create-custom-spark-pools>`_ within a workspace.
|
|
1802
|
-
|
|
1803
|
-
Parameters
|
|
1804
|
-
----------
|
|
1805
|
-
pool_name : str
|
|
1806
|
-
The custom pool name.
|
|
1807
|
-
node_size : str
|
|
1808
|
-
The `node size <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#nodesize>`_.
|
|
1809
|
-
min_node_count : int
|
|
1810
|
-
The `minimum node count <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#autoscaleproperties>`_.
|
|
1811
|
-
max_node_count : int
|
|
1812
|
-
The `maximum node count <https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#autoscaleproperties>`_.
|
|
1813
|
-
min_executors : int
|
|
1814
|
-
The `minimum executors <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#dynamicexecutorallocationproperties>`_.
|
|
1815
|
-
max_executors : int
|
|
1816
|
-
The `maximum executors <https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#dynamicexecutorallocationproperties>`_.
|
|
1817
|
-
node_family : str, default='MemoryOptimized'
|
|
1818
|
-
The `node family <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#nodefamily>`_.
|
|
1819
|
-
auto_scale_enabled : bool, default=True
|
|
1820
|
-
The status of `auto scale <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#autoscaleproperties>`_.
|
|
1821
|
-
dynamic_executor_allocation_enabled : bool, default=True
|
|
1822
|
-
The status of the `dynamic executor allocation <https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#dynamicexecutorallocationproperties>`_.
|
|
1823
|
-
workspace : str, default=None
|
|
1824
|
-
The name of the Fabric workspace.
|
|
1825
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
1826
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1827
|
-
"""
|
|
1828
|
-
|
|
1829
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool
|
|
1830
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
1831
|
-
|
|
1832
|
-
request_body = {
|
|
1833
|
-
"name": pool_name,
|
|
1834
|
-
"nodeFamily": node_family,
|
|
1835
|
-
"nodeSize": node_size,
|
|
1836
|
-
"autoScale": {
|
|
1837
|
-
"enabled": auto_scale_enabled,
|
|
1838
|
-
"minNodeCount": min_node_count,
|
|
1839
|
-
"maxNodeCount": max_node_count,
|
|
1840
|
-
},
|
|
1841
|
-
"dynamicExecutorAllocation": {
|
|
1842
|
-
"enabled": dynamic_executor_allocation_enabled,
|
|
1843
|
-
"minExecutors": min_executors,
|
|
1844
|
-
"maxExecutors": max_executors,
|
|
1845
|
-
},
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
client = fabric.FabricRestClient()
|
|
1849
|
-
response = client.post(
|
|
1850
|
-
f"/v1/workspaces/{workspace_id}/spark/pools", json=request_body
|
|
1851
|
-
)
|
|
1852
|
-
|
|
1853
|
-
if response.status_code != 201:
|
|
1854
|
-
raise FabricHTTPException(response)
|
|
1855
|
-
print(
|
|
1856
|
-
f"{icons.green_dot} The '{pool_name}' spark pool has been created within the '{workspace}' workspace."
|
|
1857
|
-
)
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
def update_custom_pool(
|
|
1861
|
-
pool_name: str,
|
|
1862
|
-
node_size: Optional[str] = None,
|
|
1863
|
-
min_node_count: Optional[int] = None,
|
|
1864
|
-
max_node_count: Optional[int] = None,
|
|
1865
|
-
min_executors: Optional[int] = None,
|
|
1866
|
-
max_executors: Optional[int] = None,
|
|
1867
|
-
node_family: Optional[str] = None,
|
|
1868
|
-
auto_scale_enabled: Optional[bool] = None,
|
|
1869
|
-
dynamic_executor_allocation_enabled: Optional[bool] = None,
|
|
1870
|
-
workspace: Optional[str] = None,
|
|
1871
|
-
):
|
|
1872
|
-
"""
|
|
1873
|
-
Updates the properties of a `custom pool <https://learn.microsoft.com/fabric/data-engineering/create-custom-spark-pools>`_ within a workspace.
|
|
1874
|
-
|
|
1875
|
-
Parameters
|
|
1876
|
-
----------
|
|
1877
|
-
pool_name : str
|
|
1878
|
-
The custom pool name.
|
|
1879
|
-
node_size : str, default=None
|
|
1880
|
-
The `node size <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#nodesize>`_.
|
|
1881
|
-
Defaults to None which keeps the existing property setting.
|
|
1882
|
-
min_node_count : int, default=None
|
|
1883
|
-
The `minimum node count <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#autoscaleproperties>`_.
|
|
1884
|
-
Defaults to None which keeps the existing property setting.
|
|
1885
|
-
max_node_count : int, default=None
|
|
1886
|
-
The `maximum node count <https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#autoscaleproperties>`_.
|
|
1887
|
-
Defaults to None which keeps the existing property setting.
|
|
1888
|
-
min_executors : int, default=None
|
|
1889
|
-
The `minimum executors <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#dynamicexecutorallocationproperties>`_.
|
|
1890
|
-
Defaults to None which keeps the existing property setting.
|
|
1891
|
-
max_executors : int, default=None
|
|
1892
|
-
The `maximum executors <https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#dynamicexecutorallocationproperties>`_.
|
|
1893
|
-
Defaults to None which keeps the existing property setting.
|
|
1894
|
-
node_family : str, default=None
|
|
1895
|
-
The `node family <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#nodefamily>`_.
|
|
1896
|
-
Defaults to None which keeps the existing property setting.
|
|
1897
|
-
auto_scale_enabled : bool, default=None
|
|
1898
|
-
The status of `auto scale <https://learn.microsoft.com/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#autoscaleproperties>`_.
|
|
1899
|
-
Defaults to None which keeps the existing property setting.
|
|
1900
|
-
dynamic_executor_allocation_enabled : bool, default=None
|
|
1901
|
-
The status of the `dynamic executor allocation <https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool?tabs=HTTP#dynamicexecutorallocationproperties>`_.
|
|
1902
|
-
Defaults to None which keeps the existing property setting.
|
|
1903
|
-
workspace : str, default=None
|
|
1904
|
-
The name of the Fabric workspace.
|
|
1905
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
1906
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1907
|
-
"""
|
|
1908
|
-
|
|
1909
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/update-workspace-custom-pool?tabs=HTTP
|
|
1910
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
1911
|
-
|
|
1912
|
-
df = list_custom_pools(workspace=workspace)
|
|
1913
|
-
df_pool = df[df["Custom Pool Name"] == pool_name]
|
|
1914
|
-
|
|
1915
|
-
if len(df_pool) == 0:
|
|
1916
|
-
raise ValueError(
|
|
1917
|
-
f"{icons.red_dot} The '{pool_name}' custom pool does not exist within the '{workspace}'. Please choose a valid custom pool."
|
|
1918
|
-
)
|
|
1919
|
-
|
|
1920
|
-
if node_family is None:
|
|
1921
|
-
node_family = df_pool["Node Family"].iloc[0]
|
|
1922
|
-
if node_size is None:
|
|
1923
|
-
node_size = df_pool["Node Size"].iloc[0]
|
|
1924
|
-
if auto_scale_enabled is None:
|
|
1925
|
-
auto_scale_enabled = bool(df_pool["Auto Scale Enabled"].iloc[0])
|
|
1926
|
-
if min_node_count is None:
|
|
1927
|
-
min_node_count = int(df_pool["Min Node Count"].iloc[0])
|
|
1928
|
-
if max_node_count is None:
|
|
1929
|
-
max_node_count = int(df_pool["Max Node Count"].iloc[0])
|
|
1930
|
-
if dynamic_executor_allocation_enabled is None:
|
|
1931
|
-
dynamic_executor_allocation_enabled = bool(
|
|
1932
|
-
df_pool["Dynami Executor Allocation Enabled"].iloc[0]
|
|
1933
|
-
)
|
|
1934
|
-
if min_executors is None:
|
|
1935
|
-
min_executors = int(df_pool["Min Executors"].iloc[0])
|
|
1936
|
-
if max_executors is None:
|
|
1937
|
-
max_executors = int(df_pool["Max Executors"].iloc[0])
|
|
1938
|
-
|
|
1939
|
-
request_body = {
|
|
1940
|
-
"name": pool_name,
|
|
1941
|
-
"nodeFamily": node_family,
|
|
1942
|
-
"nodeSize": node_size,
|
|
1943
|
-
"autoScale": {
|
|
1944
|
-
"enabled": auto_scale_enabled,
|
|
1945
|
-
"minNodeCount": min_node_count,
|
|
1946
|
-
"maxNodeCount": max_node_count,
|
|
1947
|
-
},
|
|
1948
|
-
"dynamicExecutorAllocation": {
|
|
1949
|
-
"enabled": dynamic_executor_allocation_enabled,
|
|
1950
|
-
"minExecutors": min_executors,
|
|
1951
|
-
"maxExecutors": max_executors,
|
|
1952
|
-
},
|
|
1953
|
-
}
|
|
1954
|
-
|
|
1955
|
-
client = fabric.FabricRestClient()
|
|
1956
|
-
response = client.post(
|
|
1957
|
-
f"/v1/workspaces/{workspace_id}/spark/pools", json=request_body
|
|
1958
|
-
)
|
|
1959
|
-
|
|
1960
|
-
if response.status_code != 200:
|
|
1961
|
-
raise FabricHTTPException(response)
|
|
1962
|
-
print(
|
|
1963
|
-
f"{icons.green_dot} The '{pool_name}' spark pool within the '{workspace}' workspace has been updated."
|
|
1964
|
-
)
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
def delete_custom_pool(pool_name: str, workspace: Optional[str] = None):
|
|
1968
|
-
"""
|
|
1969
|
-
Deletes a `custom pool <https://learn.microsoft.com/fabric/data-engineering/create-custom-spark-pools>`_ within a workspace.
|
|
1970
|
-
|
|
1971
|
-
Parameters
|
|
1972
|
-
----------
|
|
1973
|
-
pool_name : str
|
|
1974
|
-
The custom pool name.
|
|
1975
|
-
workspace : str, default=None
|
|
1976
|
-
The name of the Fabric workspace.
|
|
1977
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
1978
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1979
|
-
"""
|
|
1980
|
-
|
|
1981
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
1982
|
-
|
|
1983
|
-
dfL = list_custom_pools(workspace=workspace)
|
|
1984
|
-
dfL_filt = dfL[dfL["Custom Pool Name"] == pool_name]
|
|
1985
|
-
|
|
1986
|
-
if len(dfL_filt) == 0:
|
|
1987
|
-
raise ValueError(
|
|
1988
|
-
f"{icons.red_dot} The '{pool_name}' custom pool does not exist within the '{workspace}' workspace."
|
|
1989
|
-
)
|
|
1990
|
-
poolId = dfL_filt["Custom Pool ID"].iloc[0]
|
|
1991
|
-
|
|
1992
|
-
client = fabric.FabricRestClient()
|
|
1993
|
-
response = client.delete(f"/v1/workspaces/{workspace_id}/spark/pools/{poolId}")
|
|
1994
|
-
|
|
1995
|
-
if response.status_code != 200:
|
|
1996
|
-
raise FabricHTTPException(response)
|
|
1997
|
-
print(
|
|
1998
|
-
f"{icons.green_dot} The '{pool_name}' spark pool has been deleted from the '{workspace}' workspace."
|
|
1999
|
-
)
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
def assign_workspace_to_capacity(capacity_name: str, workspace: Optional[str] = None):
|
|
2003
|
-
"""
|
|
2004
|
-
Assigns a workspace to a capacity.
|
|
2005
|
-
|
|
2006
|
-
Parameters
|
|
2007
|
-
----------
|
|
2008
|
-
capacity_name : str
|
|
2009
|
-
The name of the capacity.
|
|
2010
|
-
workspace : str, default=None
|
|
2011
|
-
The name of the Fabric workspace.
|
|
2012
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2013
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
2014
|
-
"""
|
|
2015
|
-
|
|
2016
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
2017
|
-
|
|
2018
|
-
dfC = fabric.list_capacities()
|
|
2019
|
-
dfC_filt = dfC[dfC["Display Name"] == capacity_name]
|
|
2020
|
-
|
|
2021
|
-
if len(dfC_filt) == 0:
|
|
2022
|
-
raise ValueError(f"{icons.red_dot} The '{capacity_name}' capacity does not exist.")
|
|
2023
|
-
|
|
2024
|
-
capacity_id = dfC_filt["Id"].iloc[0]
|
|
2025
|
-
|
|
2026
|
-
request_body = {"capacityId": capacity_id}
|
|
2027
|
-
|
|
2028
|
-
client = fabric.FabricRestClient()
|
|
2029
|
-
response = client.post(
|
|
2030
|
-
f"/v1/workspaces/{workspace_id}/assignToCapacity",
|
|
2031
|
-
json=request_body,
|
|
2032
|
-
)
|
|
2033
|
-
|
|
2034
|
-
if response.status_code not in [200, 202]:
|
|
2035
|
-
raise FabricHTTPException(response)
|
|
2036
|
-
print(
|
|
2037
|
-
f"{icons.green_dot} The '{workspace}' workspace has been assigned to the '{capacity_name}' capacity."
|
|
2038
|
-
)
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
def unassign_workspace_from_capacity(workspace: Optional[str] = None):
|
|
2042
|
-
"""
|
|
2043
|
-
Unassigns a workspace from its assigned capacity.
|
|
2044
|
-
|
|
2045
|
-
Parameters
|
|
2046
|
-
----------
|
|
2047
|
-
workspace : str, default=None
|
|
2048
|
-
The name of the Fabric workspace.
|
|
2049
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2050
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
2051
|
-
"""
|
|
2052
|
-
|
|
2053
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/core/workspaces/unassign-from-capacity?tabs=HTTP
|
|
2054
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
2055
|
-
|
|
2056
|
-
client = fabric.FabricRestClient()
|
|
2057
|
-
response = client.post(
|
|
2058
|
-
f"/v1/workspaces/{workspace_id}/unassignFromCapacity"
|
|
2059
|
-
)
|
|
2060
|
-
|
|
2061
|
-
if response.status_code not in [200, 202]:
|
|
2062
|
-
raise FabricHTTPException(response)
|
|
2063
|
-
print(
|
|
2064
|
-
f"{icons.green_dot} The '{workspace}' workspace has been unassigned from its capacity."
|
|
2065
|
-
)
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
def get_spark_settings(workspace: Optional[str] = None) -> pd.DataFrame:
|
|
1723
|
+
def list_reports_using_semantic_model(
|
|
1724
|
+
dataset: str, workspace: Optional[str] = None
|
|
1725
|
+
) -> pd.DataFrame:
|
|
2069
1726
|
"""
|
|
2070
|
-
Shows the
|
|
1727
|
+
Shows a list of all the reports (in all workspaces) which use a given semantic model.
|
|
2071
1728
|
|
|
2072
1729
|
Parameters
|
|
2073
1730
|
----------
|
|
1731
|
+
dataset : str
|
|
1732
|
+
Name of the semantic model.
|
|
2074
1733
|
workspace : str, default=None
|
|
2075
|
-
The
|
|
1734
|
+
The Fabric workspace name.
|
|
2076
1735
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2077
1736
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
2078
1737
|
|
|
2079
1738
|
Returns
|
|
2080
1739
|
-------
|
|
2081
1740
|
pandas.DataFrame
|
|
2082
|
-
A pandas dataframe showing the
|
|
1741
|
+
A pandas dataframe showing the reports which use a given semantic model.
|
|
2083
1742
|
"""
|
|
2084
1743
|
|
|
2085
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/spark/workspace-settings/get-spark-settings?tabs=HTTP
|
|
2086
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
2087
|
-
|
|
2088
1744
|
df = pd.DataFrame(
|
|
2089
1745
|
columns=[
|
|
2090
|
-
"
|
|
2091
|
-
"
|
|
2092
|
-
"
|
|
2093
|
-
"
|
|
2094
|
-
"Default Pool Type",
|
|
2095
|
-
"Max Node Count",
|
|
2096
|
-
"Max Executors",
|
|
2097
|
-
"Environment Name",
|
|
2098
|
-
"Runtime Version",
|
|
1746
|
+
"Report Name",
|
|
1747
|
+
"Report Id",
|
|
1748
|
+
"Report Workspace Name",
|
|
1749
|
+
"Report Workspace Id",
|
|
2099
1750
|
]
|
|
2100
1751
|
)
|
|
2101
1752
|
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
1753
|
+
workspace = fabric.resolve_workspace_name(workspace)
|
|
1754
|
+
dataset_id = resolve_dataset_id(dataset, workspace)
|
|
1755
|
+
client = fabric.PowerBIRestClient()
|
|
1756
|
+
response = client.get(
|
|
1757
|
+
f"metadata/relations/downstream/dataset/{dataset_id}?apiVersion=3"
|
|
1758
|
+
)
|
|
2106
1759
|
|
|
2107
|
-
|
|
2108
|
-
p = i.get("pool")
|
|
2109
|
-
dp = i.get("pool", {}).get("defaultPool", {})
|
|
2110
|
-
sp = i.get("pool", {}).get("starterPool", {})
|
|
2111
|
-
e = i.get("environment", {})
|
|
2112
|
-
|
|
2113
|
-
new_data = {
|
|
2114
|
-
"Automatic Log Enabled": i.get("automaticLog").get("enabled"),
|
|
2115
|
-
"High Concurrency Enabled": i.get("highConcurrency").get(
|
|
2116
|
-
"notebookInteractiveRunEnabled"
|
|
2117
|
-
),
|
|
2118
|
-
"Customize Compute Enabled": p.get("customizeComputeEnabled"),
|
|
2119
|
-
"Default Pool Name": dp.get("name"),
|
|
2120
|
-
"Default Pool Type": dp.get("type"),
|
|
2121
|
-
"Max Node Count": sp.get("maxNodeCount"),
|
|
2122
|
-
"Max Node Executors": sp.get("maxExecutors"),
|
|
2123
|
-
"Environment Name": e.get("name"),
|
|
2124
|
-
"Runtime Version": e.get("runtimeVersion"),
|
|
2125
|
-
}
|
|
2126
|
-
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
1760
|
+
response_json = response.json()
|
|
2127
1761
|
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
"Customize Compute Enabled",
|
|
2132
|
-
]
|
|
2133
|
-
int_cols = ["Max Node Count", "Max Executors"]
|
|
1762
|
+
for i in response_json.get("artifacts", []):
|
|
1763
|
+
object_workspace_id = i.get("workspace", {}).get("objectId")
|
|
1764
|
+
object_type = i.get("typeName")
|
|
2134
1765
|
|
|
2135
|
-
|
|
2136
|
-
|
|
1766
|
+
if object_type == "Report":
|
|
1767
|
+
new_data = {
|
|
1768
|
+
"Report Name": i.get("displayName"),
|
|
1769
|
+
"Report Id": i.get("objectId"),
|
|
1770
|
+
"Report Workspace Name": fabric.resolve_workspace_name(
|
|
1771
|
+
object_workspace_id
|
|
1772
|
+
),
|
|
1773
|
+
"Report Workspace Id": object_workspace_id,
|
|
1774
|
+
}
|
|
1775
|
+
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
2137
1776
|
|
|
2138
1777
|
return df
|
|
2139
1778
|
|
|
2140
1779
|
|
|
2141
|
-
def
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
customize_compute_enabled: Optional[bool] = None,
|
|
2145
|
-
default_pool_name: Optional[str] = None,
|
|
2146
|
-
max_node_count: Optional[int] = None,
|
|
2147
|
-
max_executors: Optional[int] = None,
|
|
2148
|
-
environment_name: Optional[str] = None,
|
|
2149
|
-
runtime_version: Optional[str] = None,
|
|
2150
|
-
workspace: Optional[str] = None,
|
|
2151
|
-
):
|
|
1780
|
+
def list_report_semantic_model_objects(
|
|
1781
|
+
dataset: str, workspace: Optional[str] = None, extended: Optional[bool] = False
|
|
1782
|
+
) -> pd.DataFrame:
|
|
2152
1783
|
"""
|
|
2153
|
-
|
|
1784
|
+
Shows a list of semantic model objects (i.e. columns, measures, hierarchies) used in all reports which feed data from
|
|
1785
|
+
a given semantic model.
|
|
1786
|
+
|
|
1787
|
+
Requirement: Reports must be in the PBIR format.
|
|
2154
1788
|
|
|
2155
1789
|
Parameters
|
|
2156
1790
|
----------
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
Defaults to None which keeps the existing property setting.
|
|
2160
|
-
high_concurrency_enabled : bool, default=None
|
|
2161
|
-
The status of the `high concurrency <https://learn.microsoft.com/rest/api/fabric/spark/workspace-settings/update-spark-settings?tabs=HTTP#highconcurrencyproperties>`_ for notebook interactive run.
|
|
2162
|
-
Defaults to None which keeps the existing property setting.
|
|
2163
|
-
customize_compute_enabled : bool, default=None
|
|
2164
|
-
`Customize compute <https://learn.microsoft.com/rest/api/fabric/spark/workspace-settings/update-spark-settings?tabs=HTTP#poolproperties>`_ configurations for items.
|
|
2165
|
-
Defaults to None which keeps the existing property setting.
|
|
2166
|
-
default_pool_name : str, default=None
|
|
2167
|
-
`Default pool <https://learn.microsoft.com/rest/api/fabric/spark/workspace-settings/update-spark-settings?tabs=HTTP#poolproperties>`_ for workspace.
|
|
2168
|
-
Defaults to None which keeps the existing property setting.
|
|
2169
|
-
max_node_count : int, default=None
|
|
2170
|
-
The `maximum node count <https://learn.microsoft.com/en-us/rest/api/fabric/spark/workspace-settings/update-spark-settings?tabs=HTTP#starterpoolproperties>`_.
|
|
2171
|
-
Defaults to None which keeps the existing property setting.
|
|
2172
|
-
max_executors : int, default=None
|
|
2173
|
-
The `maximum executors <https://learn.microsoft.com/rest/api/fabric/spark/workspace-settings/update-spark-settings?tabs=HTTP#starterpoolproperties>`_.
|
|
2174
|
-
Defaults to None which keeps the existing property setting.
|
|
2175
|
-
environment_name : str, default=None
|
|
2176
|
-
The name of the `default environment <https://learn.microsoft.com/rest/api/fabric/spark/workspace-settings/update-spark-settings?tabs=HTTP#environmentproperties>`_. Empty string indicated there is no workspace default environment
|
|
2177
|
-
Defaults to None which keeps the existing property setting.
|
|
2178
|
-
runtime_version : str, default=None
|
|
2179
|
-
The `runtime version <https://learn.microsoft.com/rest/api/fabric/spark/workspace-settings/update-spark-settings?tabs=HTTP#environmentproperties>`_.
|
|
2180
|
-
Defaults to None which keeps the existing property setting.
|
|
1791
|
+
dataset : str
|
|
1792
|
+
Name of the semantic model.
|
|
2181
1793
|
workspace : str, default=None
|
|
2182
|
-
The
|
|
1794
|
+
The Fabric workspace name.
|
|
2183
1795
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2184
1796
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1797
|
+
extended: bool, default=False
|
|
1798
|
+
If True, adds an extra column called 'Valid Semantic Model Object' which identifies whether the semantic model object used
|
|
1799
|
+
in the report exists in the semantic model which feeds data to the report.
|
|
2185
1800
|
|
|
2186
1801
|
Returns
|
|
2187
1802
|
-------
|
|
1803
|
+
pandas.DataFrame
|
|
1804
|
+
A pandas dataframe showing a list of semantic model objects (i.e. columns, measures, hierarchies) used in all reports which feed data from
|
|
1805
|
+
a given semantic model.
|
|
2188
1806
|
"""
|
|
2189
1807
|
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
dfS = get_spark_settings(workspace=workspace)
|
|
2194
|
-
|
|
2195
|
-
if automatic_log_enabled is None:
|
|
2196
|
-
automatic_log_enabled = bool(dfS["Automatic Log Enabled"].iloc[0])
|
|
2197
|
-
if high_concurrency_enabled is None:
|
|
2198
|
-
high_concurrency_enabled = bool(dfS["High Concurrency Enabled"].iloc[0])
|
|
2199
|
-
if customize_compute_enabled is None:
|
|
2200
|
-
customize_compute_enabled = bool(dfS["Customize Compute Enabled"].iloc[0])
|
|
2201
|
-
if default_pool_name is None:
|
|
2202
|
-
default_pool_name = dfS["Default Pool Name"].iloc[0]
|
|
2203
|
-
if max_node_count is None:
|
|
2204
|
-
max_node_count = int(dfS["Max Node Count"].iloc[0])
|
|
2205
|
-
if max_executors is None:
|
|
2206
|
-
max_executors = int(dfS["Max Executors"].iloc[0])
|
|
2207
|
-
if environment_name is None:
|
|
2208
|
-
environment_name = dfS["Environment Name"].iloc[0]
|
|
2209
|
-
if runtime_version is None:
|
|
2210
|
-
runtime_version = dfS["Runtime Version"].iloc[0]
|
|
2211
|
-
|
|
2212
|
-
request_body = {
|
|
2213
|
-
"automaticLog": {"enabled": automatic_log_enabled},
|
|
2214
|
-
"highConcurrency": {"notebookInteractiveRunEnabled": high_concurrency_enabled},
|
|
2215
|
-
"pool": {
|
|
2216
|
-
"customizeComputeEnabled": customize_compute_enabled,
|
|
2217
|
-
"defaultPool": {"name": default_pool_name, "type": "Workspace"},
|
|
2218
|
-
"starterPool": {
|
|
2219
|
-
"maxNodeCount": max_node_count,
|
|
2220
|
-
"maxExecutors": max_executors,
|
|
2221
|
-
},
|
|
2222
|
-
},
|
|
2223
|
-
"environment": {"name": environment_name, "runtimeVersion": runtime_version},
|
|
2224
|
-
}
|
|
2225
|
-
|
|
2226
|
-
client = fabric.FabricRestClient()
|
|
2227
|
-
response = client.patch(
|
|
2228
|
-
f"/v1/workspaces/{workspace_id}/spark/settings", json=request_body
|
|
2229
|
-
)
|
|
2230
|
-
|
|
2231
|
-
if response.status_code != 200:
|
|
2232
|
-
raise FabricHTTPException(response)
|
|
2233
|
-
print(
|
|
2234
|
-
f"{icons.green_dot} The spark settings within the '{workspace}' workspace have been updated accordingly."
|
|
2235
|
-
)
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
def add_user_to_workspace(
|
|
2239
|
-
email_address: str,
|
|
2240
|
-
role_name: str,
|
|
2241
|
-
principal_type: Optional[str] = "User",
|
|
2242
|
-
workspace: Optional[str] = None,
|
|
2243
|
-
):
|
|
2244
|
-
"""
|
|
2245
|
-
Adds a user to a workspace.
|
|
2246
|
-
|
|
2247
|
-
Parameters
|
|
2248
|
-
----------
|
|
2249
|
-
email_address : str
|
|
2250
|
-
The email address of the user.
|
|
2251
|
-
role_name : str
|
|
2252
|
-
The `role <https://learn.microsoft.com/rest/api/power-bi/groups/add-group-user#groupuseraccessright>`_ of the user within the workspace.
|
|
2253
|
-
principal_type : str, default='User'
|
|
2254
|
-
The `principal type <https://learn.microsoft.com/rest/api/power-bi/groups/add-group-user#principaltype>`_.
|
|
2255
|
-
workspace : str, default=None
|
|
2256
|
-
The name of the workspace.
|
|
2257
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2258
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
2259
|
-
"""
|
|
2260
|
-
|
|
2261
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
2262
|
-
|
|
2263
|
-
role_names = ["Admin", "Member", "Viewer", "Contributor"]
|
|
2264
|
-
role_name = role_name.capitalize()
|
|
2265
|
-
if role_name not in role_names:
|
|
2266
|
-
raise ValueError(
|
|
2267
|
-
f"{icons.red_dot} Invalid role. The 'role_name' parameter must be one of the following: {role_names}."
|
|
2268
|
-
)
|
|
2269
|
-
plural = "n" if role_name == "Admin" else ""
|
|
2270
|
-
principal_types = ["App", "Group", "None", "User"]
|
|
2271
|
-
principal_type = principal_type.capitalize()
|
|
2272
|
-
if principal_type not in principal_types:
|
|
2273
|
-
raise ValueError(
|
|
2274
|
-
f"{icons.red_dot} Invalid princpal type. Valid options: {principal_types}."
|
|
2275
|
-
)
|
|
2276
|
-
|
|
2277
|
-
client = fabric.PowerBIRestClient()
|
|
2278
|
-
|
|
2279
|
-
request_body = {
|
|
2280
|
-
"emailAddress": email_address,
|
|
2281
|
-
"groupUserAccessRight": role_name,
|
|
2282
|
-
"principalType": principal_type,
|
|
2283
|
-
"identifier": email_address,
|
|
2284
|
-
}
|
|
2285
|
-
|
|
2286
|
-
response = client.post(
|
|
2287
|
-
f"/v1.0/myorg/groups/{workspace_id}/users", json=request_body
|
|
2288
|
-
)
|
|
1808
|
+
from sempy_labs.report import ReportWrapper
|
|
1809
|
+
from sempy_labs.tom import connect_semantic_model
|
|
2289
1810
|
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
1811
|
+
dfRO = pd.DataFrame(
|
|
1812
|
+
columns=[
|
|
1813
|
+
"Report Name",
|
|
1814
|
+
"Report Workspace Name",
|
|
1815
|
+
"Table Name",
|
|
1816
|
+
"Object Name",
|
|
1817
|
+
"Object Type",
|
|
1818
|
+
"Report Source",
|
|
1819
|
+
"Report Source Object",
|
|
1820
|
+
]
|
|
2294
1821
|
)
|
|
2295
1822
|
|
|
1823
|
+
# Collect all reports which use the semantic model
|
|
1824
|
+
dfR = list_reports_using_semantic_model(dataset=dataset, workspace=workspace)
|
|
2296
1825
|
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
Removes a user from a workspace.
|
|
1826
|
+
if len(dfR) == 0:
|
|
1827
|
+
return dfRO
|
|
2300
1828
|
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
The email address of the user.
|
|
2305
|
-
workspace : str, default=None
|
|
2306
|
-
The name of the workspace.
|
|
2307
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2308
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1829
|
+
for _, r in dfR.iterrows():
|
|
1830
|
+
report_name = r["Report Name"]
|
|
1831
|
+
report_workspace = r["Report Workspace Name"]
|
|
2309
1832
|
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
1833
|
+
rpt = ReportWrapper(report=report_name, workspace=report_workspace)
|
|
1834
|
+
# Collect all semantic model objects used in the report
|
|
1835
|
+
dfRSO = rpt.list_semantic_model_objects()
|
|
1836
|
+
dfRSO["Report Name"] = report_name
|
|
1837
|
+
dfRSO["Report Workspace Name"] = report_workspace
|
|
1838
|
+
colName = "Report Name"
|
|
1839
|
+
dfRSO.insert(0, colName, dfRSO.pop(colName))
|
|
1840
|
+
colName = "Report Workspace Name"
|
|
1841
|
+
dfRSO.insert(1, colName, dfRSO.pop(colName))
|
|
2313
1842
|
|
|
2314
|
-
|
|
1843
|
+
dfRO = pd.concat([dfRO, dfRSO], ignore_index=True)
|
|
2315
1844
|
|
|
2316
|
-
|
|
2317
|
-
|
|
1845
|
+
# Collect all semantic model objects
|
|
1846
|
+
if extended:
|
|
1847
|
+
with connect_semantic_model(
|
|
1848
|
+
dataset=dataset, readonly=True, workspace=workspace
|
|
1849
|
+
) as tom:
|
|
1850
|
+
for index, row in dfRO.iterrows():
|
|
1851
|
+
object_type = row["Object Type"]
|
|
1852
|
+
if object_type == "Measure":
|
|
1853
|
+
dfRO.at[index, "Valid Semantic Model Object"] = any(
|
|
1854
|
+
o.Name == row["Object Name"] for o in tom.all_measures()
|
|
1855
|
+
)
|
|
1856
|
+
elif object_type == "Column":
|
|
1857
|
+
dfRO.at[index, "Valid Semantic Model Object"] = any(
|
|
1858
|
+
format_dax_object_name(c.Parent.Name, c.Name)
|
|
1859
|
+
== format_dax_object_name(row["Table Name"], row["Object Name"])
|
|
1860
|
+
for c in tom.all_columns()
|
|
1861
|
+
)
|
|
1862
|
+
elif object_type == "Hierarchy":
|
|
1863
|
+
dfRO.at[index, "Valid Semantic Model Object"] = any(
|
|
1864
|
+
format_dax_object_name(h.Parent.Name, h.Name)
|
|
1865
|
+
== format_dax_object_name(row["Table Name"], row["Object Name"])
|
|
1866
|
+
for h in tom.all_hierarchies()
|
|
1867
|
+
)
|
|
2318
1868
|
|
|
2319
|
-
|
|
2320
|
-
raise FabricHTTPException(response)
|
|
2321
|
-
print(
|
|
2322
|
-
f"{icons.green_dot} The '{email_address}' user has been removed from accessing the '{workspace}' workspace."
|
|
2323
|
-
)
|
|
1869
|
+
return dfRO
|
|
2324
1870
|
|
|
2325
1871
|
|
|
2326
|
-
def
|
|
2327
|
-
|
|
2328
|
-
role_name: str,
|
|
2329
|
-
principal_type: Optional[str] = "User",
|
|
1872
|
+
def list_semantic_model_object_report_usage(
|
|
1873
|
+
dataset: str,
|
|
2330
1874
|
workspace: Optional[str] = None,
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
Parameters
|
|
2336
|
-
----------
|
|
2337
|
-
email_address : str
|
|
2338
|
-
The email address of the user.
|
|
2339
|
-
role_name : str
|
|
2340
|
-
The `role <https://learn.microsoft.com/rest/api/power-bi/groups/add-group-user#groupuseraccessright>`_ of the user within the workspace.
|
|
2341
|
-
principal_type : str, default='User'
|
|
2342
|
-
The `principal type <https://learn.microsoft.com/rest/api/power-bi/groups/add-group-user#principaltype>`_.
|
|
2343
|
-
workspace : str, default=None
|
|
2344
|
-
The name of the workspace.
|
|
2345
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2346
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1875
|
+
include_dependencies: Optional[bool] = False,
|
|
1876
|
+
extended: Optional[bool] = False,
|
|
1877
|
+
) -> pd.DataFrame:
|
|
2347
1878
|
"""
|
|
1879
|
+
Shows a list of semantic model objects and how many times they are referenced in all reports which rely on this semantic model.
|
|
2348
1880
|
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
role_names = ["Admin", "Member", "Viewer", "Contributor"]
|
|
2352
|
-
role_name = role_name.capitalize()
|
|
2353
|
-
if role_name not in role_names:
|
|
2354
|
-
raise ValueError(
|
|
2355
|
-
f"{icons.red_dot} Invalid role. The 'role_name' parameter must be one of the following: {role_names}."
|
|
2356
|
-
)
|
|
2357
|
-
principal_types = ["App", "Group", "None", "User"]
|
|
2358
|
-
principal_type = principal_type.capitalize()
|
|
2359
|
-
if principal_type not in principal_types:
|
|
2360
|
-
raise ValueError(
|
|
2361
|
-
f"{icons.red_dot} Invalid princpal type. Valid options: {principal_types}."
|
|
2362
|
-
)
|
|
2363
|
-
|
|
2364
|
-
request_body = {
|
|
2365
|
-
"emailAddress": email_address,
|
|
2366
|
-
"groupUserAccessRight": role_name,
|
|
2367
|
-
"principalType": principal_type,
|
|
2368
|
-
"identifier": email_address,
|
|
2369
|
-
}
|
|
2370
|
-
|
|
2371
|
-
client = fabric.PowerBIRestClient()
|
|
2372
|
-
response = client.put(f"/v1.0/myorg/groups/{workspace_id}/users", json=request_body)
|
|
2373
|
-
|
|
2374
|
-
if response.status_code != 200:
|
|
2375
|
-
raise FabricHTTPException(response)
|
|
2376
|
-
print(
|
|
2377
|
-
f"{icons.green_dot} The '{email_address}' user has been updated to a '{role_name}' within the '{workspace}' workspace."
|
|
2378
|
-
)
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
def list_workspace_users(workspace: Optional[str] = None) -> pd.DataFrame:
|
|
2382
|
-
"""
|
|
2383
|
-
A list of all the users of a workspace and their roles.
|
|
1881
|
+
Requirement: Reports must be in the PBIR format.
|
|
2384
1882
|
|
|
2385
1883
|
Parameters
|
|
2386
1884
|
----------
|
|
1885
|
+
dataset : str
|
|
1886
|
+
Name of the semantic model.
|
|
2387
1887
|
workspace : str, default=None
|
|
2388
|
-
The
|
|
1888
|
+
The Fabric workspace name.
|
|
2389
1889
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2390
1890
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1891
|
+
include_dependencies : bool, default=False
|
|
1892
|
+
If True, includes measure dependencies.
|
|
1893
|
+
extended: bool, default=False
|
|
1894
|
+
If True, adds columns 'Total Size', 'Data Size', 'Dictionary Size', 'Hierarchy Size' based on Vertipaq statistics.
|
|
2391
1895
|
|
|
2392
1896
|
Returns
|
|
2393
1897
|
-------
|
|
2394
1898
|
pandas.DataFrame
|
|
2395
|
-
A pandas dataframe
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
2399
|
-
|
|
2400
|
-
df = pd.DataFrame(columns=["User Name", "Email Address", "Role", "Type", "User ID"])
|
|
2401
|
-
client = fabric.FabricRestClient()
|
|
2402
|
-
response = client.get(f"/v1/workspaces/{workspace_id}/roleAssignments")
|
|
2403
|
-
if response.status_code != 200:
|
|
2404
|
-
raise FabricHTTPException(response)
|
|
2405
|
-
|
|
2406
|
-
responses = pagination(client, response)
|
|
2407
|
-
|
|
2408
|
-
for r in responses:
|
|
2409
|
-
for v in r.get("value", []):
|
|
2410
|
-
p = v.get("principal", {})
|
|
2411
|
-
new_data = {
|
|
2412
|
-
"User Name": p.get("displayName"),
|
|
2413
|
-
"User ID": p.get("id"),
|
|
2414
|
-
"Type": p.get("type"),
|
|
2415
|
-
"Role": v.get("role"),
|
|
2416
|
-
"Email Address": p.get("userDetails", {}).get("userPrincipalName"),
|
|
2417
|
-
}
|
|
2418
|
-
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
2419
|
-
|
|
2420
|
-
return df
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
def list_capacities() -> pd.DataFrame:
|
|
2424
|
-
"""
|
|
2425
|
-
Shows the capacities and their properties.
|
|
2426
|
-
|
|
2427
|
-
Parameters
|
|
2428
|
-
----------
|
|
2429
|
-
|
|
2430
|
-
Returns
|
|
2431
|
-
-------
|
|
2432
|
-
pandas.DataFrame
|
|
2433
|
-
A pandas dataframe showing the capacities and their properties
|
|
2434
|
-
"""
|
|
2435
|
-
|
|
2436
|
-
df = pd.DataFrame(
|
|
2437
|
-
columns=["Id", "Display Name", "Sku", "Region", "State", "Admins"]
|
|
2438
|
-
)
|
|
2439
|
-
|
|
2440
|
-
client = fabric.PowerBIRestClient()
|
|
2441
|
-
response = client.get("/v1.0/myorg/capacities")
|
|
2442
|
-
if response.status_code != 200:
|
|
2443
|
-
raise FabricHTTPException(response)
|
|
2444
|
-
|
|
2445
|
-
for i in response.json().get("value", []):
|
|
2446
|
-
new_data = {
|
|
2447
|
-
"Id": i.get("id").lower(),
|
|
2448
|
-
"Display Name": i.get("displayName"),
|
|
2449
|
-
"Sku": i.get("sku"),
|
|
2450
|
-
"Region": i.get("region"),
|
|
2451
|
-
"State": i.get("state"),
|
|
2452
|
-
"Admins": [i.get("admins", [])],
|
|
2453
|
-
}
|
|
2454
|
-
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
2455
|
-
|
|
2456
|
-
return df
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
def get_notebook_definition(
|
|
2460
|
-
notebook_name: str, workspace: Optional[str] = None, decode: Optional[bool] = True
|
|
2461
|
-
):
|
|
1899
|
+
A pandas dataframe showing a list of semantic model objects and how many times they are referenced in all reports which rely on this semantic model. By default, the dataframe
|
|
1900
|
+
is sorted descending by 'Report Usage Count'.
|
|
2462
1901
|
"""
|
|
2463
|
-
Obtains the notebook definition.
|
|
2464
|
-
|
|
2465
|
-
Parameters
|
|
2466
|
-
----------
|
|
2467
|
-
notebook_name : str
|
|
2468
|
-
The name of the notebook.
|
|
2469
|
-
workspace : str, default=None
|
|
2470
|
-
The name of the workspace.
|
|
2471
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2472
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
2473
|
-
decode : bool, default=True
|
|
2474
|
-
If True, decodes the notebook definition file into .ipynb format.
|
|
2475
|
-
If False, obtains the notebook definition file in base64 format.
|
|
2476
1902
|
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
ipynb
|
|
2480
|
-
The notebook definition.
|
|
2481
|
-
"""
|
|
1903
|
+
from sempy_labs._model_dependencies import get_measure_dependencies
|
|
1904
|
+
from sempy_labs._helper_functions import format_dax_object_name
|
|
2482
1905
|
|
|
2483
|
-
|
|
1906
|
+
workspace = fabric.resolve_workspace_name(workspace)
|
|
2484
1907
|
|
|
2485
|
-
|
|
2486
|
-
|
|
1908
|
+
dfR = list_report_semantic_model_objects(dataset=dataset, workspace=workspace)
|
|
1909
|
+
usage_column_name = "Report Usage Count"
|
|
2487
1910
|
|
|
2488
|
-
if
|
|
2489
|
-
|
|
2490
|
-
|
|
1911
|
+
if not include_dependencies:
|
|
1912
|
+
final_df = (
|
|
1913
|
+
dfR.groupby(["Table Name", "Object Name", "Object Type"])
|
|
1914
|
+
.size()
|
|
1915
|
+
.reset_index(name=usage_column_name)
|
|
2491
1916
|
)
|
|
2492
|
-
|
|
2493
|
-
notebook_id = dfI_filt["Id"].iloc[0]
|
|
2494
|
-
client = fabric.FabricRestClient()
|
|
2495
|
-
response = client.post(
|
|
2496
|
-
f"v1/workspaces/{workspace_id}/notebooks/{notebook_id}/getDefinition",
|
|
2497
|
-
)
|
|
2498
|
-
|
|
2499
|
-
result = lro(client, response).json()
|
|
2500
|
-
df_items = pd.json_normalize(result["definition"]["parts"])
|
|
2501
|
-
df_items_filt = df_items[df_items["path"] == "notebook-content.py"]
|
|
2502
|
-
payload = df_items_filt["payload"].iloc[0]
|
|
2503
|
-
|
|
2504
|
-
if decode:
|
|
2505
|
-
result = _decode_b64(payload)
|
|
2506
1917
|
else:
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
return result
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
def import_notebook_from_web(
|
|
2513
|
-
notebook_name: str,
|
|
2514
|
-
url: str,
|
|
2515
|
-
description: Optional[str] = None,
|
|
2516
|
-
workspace: Optional[str] = None,
|
|
2517
|
-
):
|
|
2518
|
-
"""
|
|
2519
|
-
Creates a new notebook within a workspace based on a Jupyter notebook hosted in the web.
|
|
1918
|
+
df = pd.DataFrame(columns=["Table Name", "Object Name", "Object Type"])
|
|
1919
|
+
dep = get_measure_dependencies(dataset=dataset, workspace=workspace)
|
|
2520
1920
|
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
1921
|
+
for i, r in dfR.iterrows():
|
|
1922
|
+
object_type = r["Object Type"]
|
|
1923
|
+
table_name = r["Table Name"]
|
|
1924
|
+
object_name = r["Object Name"]
|
|
1925
|
+
new_data = {
|
|
1926
|
+
"Table Name": table_name,
|
|
1927
|
+
"Object Name": object_name,
|
|
1928
|
+
"Object Type": object_type,
|
|
1929
|
+
}
|
|
1930
|
+
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
1931
|
+
if object_type == "Measure":
|
|
1932
|
+
df_filt = dep[dep["Object Name"] == object_name][
|
|
1933
|
+
["Referenced Table", "Referenced Object", "Referenced Object Type"]
|
|
1934
|
+
]
|
|
1935
|
+
df_filt.rename(
|
|
1936
|
+
columns={
|
|
1937
|
+
"Referenced Table": "Table Name",
|
|
1938
|
+
"Referenced Object": "Object Name",
|
|
1939
|
+
"Referenced Object Type": "Object Type",
|
|
1940
|
+
},
|
|
1941
|
+
inplace=True,
|
|
1942
|
+
)
|
|
2534
1943
|
|
|
2535
|
-
|
|
2536
|
-
-------
|
|
2537
|
-
"""
|
|
1944
|
+
df = pd.concat([df, df_filt], ignore_index=True)
|
|
2538
1945
|
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
if len(dfI_filt) > 0:
|
|
2544
|
-
raise ValueError(
|
|
2545
|
-
f"{icons.red_dot} The '{notebook_name}' already exists within the '{workspace}' workspace."
|
|
1946
|
+
final_df = (
|
|
1947
|
+
df.groupby(["Table Name", "Object Name", "Object Type"])
|
|
1948
|
+
.size()
|
|
1949
|
+
.reset_index(name=usage_column_name)
|
|
2546
1950
|
)
|
|
2547
1951
|
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
if url.startswith(starting_text):
|
|
2552
|
-
url = f"https://raw.githubusercontent.com/{url[starting_text_len:]}".replace(
|
|
2553
|
-
"/blob/", "/"
|
|
1952
|
+
if extended:
|
|
1953
|
+
final_df["Object"] = format_dax_object_name(
|
|
1954
|
+
final_df["Table Name"], final_df["Object Name"]
|
|
2554
1955
|
)
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
{
|
|
2568
|
-
"path": "notebook-content.py",
|
|
2569
|
-
"payload": notebook_payload,
|
|
2570
|
-
"payloadType": "InlineBase64",
|
|
2571
|
-
}
|
|
1956
|
+
dfC = fabric.list_columns(dataset=dataset, workspace=workspace, extended=True)
|
|
1957
|
+
dfC["Object"] = format_dax_object_name(dfC["Table Name"], dfC["Column Name"])
|
|
1958
|
+
final_df = pd.merge(
|
|
1959
|
+
final_df,
|
|
1960
|
+
dfC[
|
|
1961
|
+
[
|
|
1962
|
+
"Object",
|
|
1963
|
+
"Total Size",
|
|
1964
|
+
"Data Size",
|
|
1965
|
+
"Dictionary Size",
|
|
1966
|
+
"Hierarchy Size",
|
|
1967
|
+
]
|
|
2572
1968
|
],
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
request_body["description"] = description
|
|
2577
|
-
|
|
2578
|
-
response = client.post(f"v1/workspaces/{workspace_id}/notebooks", json=request_body)
|
|
2579
|
-
|
|
2580
|
-
lro(client, response, status_codes=[201, 202])
|
|
2581
|
-
|
|
2582
|
-
print(
|
|
2583
|
-
f"{icons.green_dot} The '{notebook_name}' notebook was created within the '{workspace}' workspace."
|
|
2584
|
-
)
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
def list_reports_using_semantic_model(
|
|
2588
|
-
dataset: str, workspace: Optional[str] = None
|
|
2589
|
-
) -> pd.DataFrame:
|
|
2590
|
-
"""
|
|
2591
|
-
Shows a list of all the reports (in all workspaces) which use a given semantic model.
|
|
2592
|
-
|
|
2593
|
-
Parameters
|
|
2594
|
-
----------
|
|
2595
|
-
dataset : str
|
|
2596
|
-
Name of the semantic model.
|
|
2597
|
-
workspace : str, default=None
|
|
2598
|
-
The Fabric workspace name.
|
|
2599
|
-
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
2600
|
-
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
1969
|
+
on="Object",
|
|
1970
|
+
how="left",
|
|
1971
|
+
)
|
|
2601
1972
|
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
A pandas dataframe showing the reports which use a given semantic model.
|
|
2606
|
-
"""
|
|
1973
|
+
ext_int_cols = ["Total Size", "Data Size", "Dictionary Size", "Hierarchy Size"]
|
|
1974
|
+
final_df[ext_int_cols] = final_df[ext_int_cols].fillna(0).astype(int)
|
|
1975
|
+
final_df.drop("Object", axis=1, inplace=True)
|
|
2607
1976
|
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
"Report Name",
|
|
2611
|
-
"Report Id",
|
|
2612
|
-
"Report Workspace Name",
|
|
2613
|
-
"Report Workspace Id",
|
|
2614
|
-
]
|
|
2615
|
-
)
|
|
1977
|
+
int_cols = [usage_column_name]
|
|
1978
|
+
final_df[int_cols] = final_df[int_cols].astype(int)
|
|
2616
1979
|
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
client = fabric.PowerBIRestClient()
|
|
2620
|
-
response = client.get(
|
|
2621
|
-
f"metadata/relations/downstream/dataset/{dataset_id}?apiVersion=3"
|
|
1980
|
+
final_df = final_df[final_df["Object Type"] != "Table"].sort_values(
|
|
1981
|
+
by=usage_column_name, ascending=False
|
|
2622
1982
|
)
|
|
2623
1983
|
|
|
2624
|
-
|
|
1984
|
+
final_df.reset_index(drop=True, inplace=True)
|
|
2625
1985
|
|
|
2626
|
-
|
|
2627
|
-
object_workspace_id = i.get("workspace", {}).get("objectId")
|
|
2628
|
-
object_type = i.get("typeName")
|
|
2629
|
-
|
|
2630
|
-
if object_type == "Report":
|
|
2631
|
-
new_data = {
|
|
2632
|
-
"Report Name": i.get("displayName"),
|
|
2633
|
-
"Report Id": i.get("objectId"),
|
|
2634
|
-
"Report Workspace Name": fabric.resolve_workspace_name(
|
|
2635
|
-
object_workspace_id
|
|
2636
|
-
),
|
|
2637
|
-
"Report Workspace Id": object_workspace_id,
|
|
2638
|
-
}
|
|
2639
|
-
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
2640
|
-
|
|
2641
|
-
return df
|
|
1986
|
+
return final_df
|