semantic-link-labs 0.8.10__py3-none-any.whl → 0.8.11__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.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/METADATA +3 -2
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/RECORD +73 -72
- sempy_labs/__init__.py +6 -2
- sempy_labs/_clear_cache.py +39 -37
- sempy_labs/_connections.py +13 -13
- sempy_labs/_data_pipelines.py +20 -20
- sempy_labs/_dataflows.py +27 -28
- sempy_labs/_dax.py +41 -47
- sempy_labs/_environments.py +26 -23
- sempy_labs/_eventhouses.py +16 -15
- sempy_labs/_eventstreams.py +16 -15
- sempy_labs/_external_data_shares.py +18 -20
- sempy_labs/_gateways.py +14 -14
- sempy_labs/_generate_semantic_model.py +99 -62
- sempy_labs/_git.py +105 -43
- sempy_labs/_helper_functions.py +148 -131
- sempy_labs/_job_scheduler.py +92 -0
- sempy_labs/_kql_databases.py +16 -15
- sempy_labs/_kql_querysets.py +16 -15
- sempy_labs/_list_functions.py +114 -99
- sempy_labs/_managed_private_endpoints.py +19 -17
- sempy_labs/_mirrored_databases.py +51 -48
- sempy_labs/_mirrored_warehouses.py +5 -4
- sempy_labs/_ml_experiments.py +16 -15
- sempy_labs/_ml_models.py +15 -14
- sempy_labs/_model_bpa.py +3 -3
- sempy_labs/_model_dependencies.py +55 -29
- sempy_labs/_notebooks.py +27 -25
- sempy_labs/_one_lake_integration.py +23 -26
- sempy_labs/_query_scale_out.py +67 -64
- sempy_labs/_refresh_semantic_model.py +25 -26
- sempy_labs/_spark.py +33 -32
- sempy_labs/_sql.py +12 -9
- sempy_labs/_translations.py +10 -7
- sempy_labs/_vertipaq.py +34 -31
- sempy_labs/_warehouses.py +22 -21
- sempy_labs/_workspace_identity.py +11 -10
- sempy_labs/_workspaces.py +40 -33
- sempy_labs/admin/_basic_functions.py +10 -12
- sempy_labs/admin/_external_data_share.py +3 -3
- sempy_labs/admin/_items.py +4 -4
- sempy_labs/admin/_scanner.py +3 -1
- sempy_labs/directlake/_directlake_schema_compare.py +18 -14
- sempy_labs/directlake/_directlake_schema_sync.py +18 -12
- sempy_labs/directlake/_dl_helper.py +25 -26
- sempy_labs/directlake/_generate_shared_expression.py +10 -9
- sempy_labs/directlake/_get_directlake_lakehouse.py +16 -13
- sempy_labs/directlake/_get_shared_expression.py +4 -3
- sempy_labs/directlake/_guardrails.py +12 -6
- sempy_labs/directlake/_list_directlake_model_calc_tables.py +15 -9
- sempy_labs/directlake/_show_unsupported_directlake_objects.py +16 -10
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +35 -31
- sempy_labs/directlake/_update_directlake_partition_entity.py +34 -31
- sempy_labs/directlake/_warm_cache.py +87 -65
- sempy_labs/lakehouse/_get_lakehouse_columns.py +10 -8
- sempy_labs/lakehouse/_get_lakehouse_tables.py +10 -9
- sempy_labs/lakehouse/_lakehouse.py +17 -13
- sempy_labs/lakehouse/_shortcuts.py +42 -23
- sempy_labs/migration/_create_pqt_file.py +16 -11
- sempy_labs/migration/_refresh_calc_tables.py +16 -10
- sempy_labs/report/_download_report.py +9 -8
- sempy_labs/report/_generate_report.py +40 -44
- sempy_labs/report/_paginated.py +9 -9
- sempy_labs/report/_report_bpa.py +13 -9
- sempy_labs/report/_report_functions.py +80 -91
- sempy_labs/report/_report_helper.py +8 -4
- sempy_labs/report/_report_list_functions.py +24 -13
- sempy_labs/report/_report_rebind.py +17 -16
- sempy_labs/report/_reportwrapper.py +41 -33
- sempy_labs/tom/_model.py +43 -6
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/top_level.txt +0 -0
|
@@ -23,11 +23,12 @@ from typing import List, Optional, Union
|
|
|
23
23
|
from sempy._utils._log import log
|
|
24
24
|
import sempy_labs._icons as icons
|
|
25
25
|
from sempy.fabric.exceptions import FabricHTTPException
|
|
26
|
+
from uuid import UUID
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
def get_report_json(
|
|
29
30
|
report: str,
|
|
30
|
-
workspace: Optional[str] = None,
|
|
31
|
+
workspace: Optional[str | UUID] = None,
|
|
31
32
|
save_to_file_name: Optional[str] = None,
|
|
32
33
|
) -> dict:
|
|
33
34
|
"""
|
|
@@ -39,8 +40,8 @@ def get_report_json(
|
|
|
39
40
|
----------
|
|
40
41
|
report : str
|
|
41
42
|
Name of the Power BI report.
|
|
42
|
-
workspace : str, default=None
|
|
43
|
-
The Fabric workspace name in which the report exists.
|
|
43
|
+
workspace : str | uuid.UUID, default=None
|
|
44
|
+
The Fabric workspace name or ID in which the report exists.
|
|
44
45
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
45
46
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
46
47
|
save_to_file_name : str, default=None
|
|
@@ -52,8 +53,8 @@ def get_report_json(
|
|
|
52
53
|
The report.json file for a given Power BI report.
|
|
53
54
|
"""
|
|
54
55
|
|
|
55
|
-
(
|
|
56
|
-
report_id = resolve_report_id(report=report, workspace=
|
|
56
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
57
|
+
report_id = resolve_report_id(report=report, workspace=workspace_id)
|
|
57
58
|
fmt = "PBIR-Legacy"
|
|
58
59
|
|
|
59
60
|
client = fabric.FabricRestClient()
|
|
@@ -91,24 +92,22 @@ def get_report_json(
|
|
|
91
92
|
return report_json
|
|
92
93
|
|
|
93
94
|
|
|
94
|
-
def report_dependency_tree(workspace: Optional[str] = None):
|
|
95
|
+
def report_dependency_tree(workspace: Optional[str | UUID] = None):
|
|
95
96
|
"""
|
|
96
97
|
Prints a dependency between reports and semantic models.
|
|
97
98
|
|
|
98
99
|
Parameters
|
|
99
100
|
----------
|
|
100
|
-
workspace : str, default=None
|
|
101
|
-
The Fabric workspace name.
|
|
101
|
+
workspace : str | uuid.UUID, default=None
|
|
102
|
+
The Fabric workspace name or ID.
|
|
102
103
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
103
104
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
104
105
|
"""
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
workspaceId = fabric.get_workspace_id()
|
|
108
|
-
workspace = fabric.resolve_workspace_name(workspaceId)
|
|
107
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
109
108
|
|
|
110
|
-
dfR = fabric.list_reports(workspace=
|
|
111
|
-
dfD = fabric.list_datasets(workspace=
|
|
109
|
+
dfR = fabric.list_reports(workspace=workspace_id)
|
|
110
|
+
dfD = fabric.list_datasets(workspace=workspace_id)
|
|
112
111
|
dfR = pd.merge(
|
|
113
112
|
dfR,
|
|
114
113
|
dfD[["Dataset ID", "Dataset Name"]],
|
|
@@ -124,11 +123,11 @@ def report_dependency_tree(workspace: Optional[str] = None):
|
|
|
124
123
|
workspace_icon = "\U0001F465"
|
|
125
124
|
|
|
126
125
|
node_dict = {}
|
|
127
|
-
rootNode = Node(
|
|
128
|
-
node_dict[
|
|
126
|
+
rootNode = Node(workspace_name)
|
|
127
|
+
node_dict[workspace_name] = rootNode
|
|
129
128
|
rootNode.custom_property = f"{workspace_icon} "
|
|
130
129
|
|
|
131
|
-
for
|
|
130
|
+
for _, r in dfR.iterrows():
|
|
132
131
|
datasetName = r["Dataset Name"]
|
|
133
132
|
reportName = r["Report Name"]
|
|
134
133
|
parentNode = node_dict.get(datasetName)
|
|
@@ -141,7 +140,7 @@ def report_dependency_tree(workspace: Optional[str] = None):
|
|
|
141
140
|
child_node.custom_property = f"{report_icon} "
|
|
142
141
|
|
|
143
142
|
# Print the tree structure
|
|
144
|
-
for pre, _, node in RenderTree(node_dict[
|
|
143
|
+
for pre, _, node in RenderTree(node_dict[workspace_name]):
|
|
145
144
|
print(f"{pre}{node.custom_property}'{node.name}'")
|
|
146
145
|
|
|
147
146
|
|
|
@@ -154,7 +153,7 @@ def export_report(
|
|
|
154
153
|
page_name: Optional[str] = None,
|
|
155
154
|
visual_name: Optional[str] = None,
|
|
156
155
|
report_filter: Optional[str] = None,
|
|
157
|
-
workspace: Optional[str] = None,
|
|
156
|
+
workspace: Optional[str | UUID] = None,
|
|
158
157
|
):
|
|
159
158
|
"""
|
|
160
159
|
Exports a Power BI report to a file in your lakehouse.
|
|
@@ -178,22 +177,18 @@ def export_report(
|
|
|
178
177
|
The name (GUID) of a visual. If you specify this parameter you must also specify the page_name parameter.
|
|
179
178
|
report_filter : str, default=None
|
|
180
179
|
A report filter to be applied when exporting the report. Syntax is user-friendly. See above for examples.
|
|
181
|
-
workspace : str, default=None
|
|
182
|
-
The Fabric workspace name.
|
|
180
|
+
workspace : str | uuid.UUID, default=None
|
|
181
|
+
The Fabric workspace name or ID.
|
|
183
182
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
184
183
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
185
184
|
"""
|
|
186
185
|
|
|
187
|
-
# https://learn.microsoft.com/rest/api/power-bi/reports/export-to-file-in-group
|
|
188
|
-
# https://learn.microsoft.com/rest/api/power-bi/reports/get-export-to-file-status-in-group
|
|
189
|
-
# https://learn.microsoft.com/rest/api/power-bi/reports/get-file-of-export-to-file-in-group
|
|
190
|
-
|
|
191
186
|
if not lakehouse_attached():
|
|
192
187
|
raise ValueError(
|
|
193
188
|
f"{icons.red_dot} In order to run the 'export_report' function, a lakehouse must be attached to the notebook. Please attach a lakehouse to this notebook."
|
|
194
189
|
)
|
|
195
190
|
|
|
196
|
-
(
|
|
191
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
197
192
|
|
|
198
193
|
if isinstance(page_name, str):
|
|
199
194
|
page_name = [page_name]
|
|
@@ -242,7 +237,7 @@ def export_report(
|
|
|
242
237
|
folderPath = "/lakehouse/default/Files"
|
|
243
238
|
filePath = os.path.join(folderPath, file_name)
|
|
244
239
|
|
|
245
|
-
dfI = fabric.list_items(workspace=
|
|
240
|
+
dfI = fabric.list_items(workspace=workspace_id)
|
|
246
241
|
dfI_filt = dfI[
|
|
247
242
|
(dfI["Type"].isin(["Report", "PaginatedReport"]))
|
|
248
243
|
& (dfI["Display Name"] == report)
|
|
@@ -250,7 +245,7 @@ def export_report(
|
|
|
250
245
|
|
|
251
246
|
if len(dfI_filt) == 0:
|
|
252
247
|
raise ValueError(
|
|
253
|
-
f"{icons.red_dot} The '{report}' report does not exist in the '{
|
|
248
|
+
f"{icons.red_dot} The '{report}' report does not exist in the '{workspace_name}' workspace."
|
|
254
249
|
)
|
|
255
250
|
|
|
256
251
|
reportType = dfI_filt["Type"].iloc[0]
|
|
@@ -316,13 +311,13 @@ def export_report(
|
|
|
316
311
|
request_body = {"format": export_format, "powerBIReportConfiguration": {}}
|
|
317
312
|
|
|
318
313
|
request_body["powerBIReportConfiguration"]["pages"] = []
|
|
319
|
-
dfPage = list_report_pages(report=report, workspace=
|
|
314
|
+
dfPage = list_report_pages(report=report, workspace=workspace_id)
|
|
320
315
|
|
|
321
316
|
for page in page_name:
|
|
322
317
|
dfPage_filt = dfPage[dfPage["Page ID"] == page]
|
|
323
318
|
if len(dfPage_filt) == 0:
|
|
324
319
|
raise ValueError(
|
|
325
|
-
f"{icons.red_dot} The '{page}' page does not exist in the '{report}' report within the '{
|
|
320
|
+
f"{icons.red_dot} The '{page}' page does not exist in the '{report}' report within the '{workspace_name}' workspace."
|
|
326
321
|
)
|
|
327
322
|
|
|
328
323
|
page_dict = {"pageName": page}
|
|
@@ -338,7 +333,7 @@ def export_report(
|
|
|
338
333
|
request_body = {"format": export_format, "powerBIReportConfiguration": {}}
|
|
339
334
|
|
|
340
335
|
request_body["powerBIReportConfiguration"]["pages"] = []
|
|
341
|
-
dfVisual = list_report_visuals(report=report, workspace=
|
|
336
|
+
dfVisual = list_report_visuals(report=report, workspace=workspace_id)
|
|
342
337
|
a = 0
|
|
343
338
|
for page in page_name:
|
|
344
339
|
visual = visual_name[a]
|
|
@@ -348,7 +343,7 @@ def export_report(
|
|
|
348
343
|
]
|
|
349
344
|
if len(dfVisual_filt) == 0:
|
|
350
345
|
raise ValueError(
|
|
351
|
-
f"{icons.red_dot} The '{visual}' visual does not exist on the '{page}' in the '{report}' report within the '{
|
|
346
|
+
f"{icons.red_dot} The '{visual}' visual does not exist on the '{page}' in the '{report}' report within the '{workspace_name}' workspace."
|
|
352
347
|
)
|
|
353
348
|
|
|
354
349
|
page_dict = {"pageName": page, "visualName": visual}
|
|
@@ -380,24 +375,24 @@ def export_report(
|
|
|
380
375
|
response_body = json.loads(response.content)
|
|
381
376
|
if response_body["status"] == "Failed":
|
|
382
377
|
raise ValueError(
|
|
383
|
-
f"{icons.red_dot} The export for the '{report}' report within the '{
|
|
378
|
+
f"{icons.red_dot} The export for the '{report}' report within the '{workspace_name}' workspace in the '{export_format}' format has failed."
|
|
384
379
|
)
|
|
385
380
|
else:
|
|
386
381
|
response = client.get(f"{base_url}/exports/{export_id}/file")
|
|
387
382
|
print(
|
|
388
|
-
f"{icons.in_progress} Saving the '{export_format}' export for the '{report}' report within the '{
|
|
383
|
+
f"{icons.in_progress} Saving the '{export_format}' export for the '{report}' report within the '{workspace_name}' workspace to the lakehouse..."
|
|
389
384
|
)
|
|
390
385
|
with open(filePath, "wb") as export_file:
|
|
391
386
|
export_file.write(response.content)
|
|
392
387
|
print(
|
|
393
|
-
f"{icons.green_dot} The '{export_format}' export for the '{report}' report within the '{
|
|
388
|
+
f"{icons.green_dot} The '{export_format}' export for the '{report}' report within the '{workspace_name}' workspace has been saved to the following location: '{filePath}'."
|
|
394
389
|
)
|
|
395
390
|
|
|
396
391
|
|
|
397
392
|
def clone_report(
|
|
398
393
|
report: str,
|
|
399
394
|
cloned_report: str,
|
|
400
|
-
workspace: Optional[str] = None,
|
|
395
|
+
workspace: Optional[str | UUID] = None,
|
|
401
396
|
target_workspace: Optional[str] = None,
|
|
402
397
|
target_dataset: Optional[str] = None,
|
|
403
398
|
target_dataset_workspace: Optional[str] = None,
|
|
@@ -413,8 +408,8 @@ def clone_report(
|
|
|
413
408
|
Name of the Power BI report.
|
|
414
409
|
cloned_report : str
|
|
415
410
|
Name of the new Power BI report.
|
|
416
|
-
workspace : str, default=None
|
|
417
|
-
The Fabric workspace name.
|
|
411
|
+
workspace : str | uuid.UUID, default=None
|
|
412
|
+
The Fabric workspace name or ID.
|
|
418
413
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
419
414
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
420
415
|
target_workspace : str, default=None
|
|
@@ -425,38 +420,36 @@ def clone_report(
|
|
|
425
420
|
The name of the semantic model to be used by the cloned report.
|
|
426
421
|
Defaults to None which resolves to the semantic model used by the initial report.
|
|
427
422
|
target_dataset_workspace : str, default=None
|
|
428
|
-
The workspace in which the semantic model to be used by the report resides.
|
|
423
|
+
The workspace name in which the semantic model to be used by the report resides.
|
|
429
424
|
Defaults to None which resolves to the semantic model used by the initial report.
|
|
430
425
|
"""
|
|
431
426
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
427
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
435
428
|
|
|
436
|
-
dfI = fabric.list_items(workspace=
|
|
429
|
+
dfI = fabric.list_items(workspace=workspace_id, type="Report")
|
|
437
430
|
dfI_filt = dfI[(dfI["Display Name"] == report)]
|
|
438
431
|
|
|
439
432
|
if len(dfI_filt) == 0:
|
|
440
433
|
raise ValueError(
|
|
441
|
-
f"{icons.red_dot} The '{report}' report does not exist within the '{
|
|
434
|
+
f"{icons.red_dot} The '{report}' report does not exist within the '{workspace_name}' workspace."
|
|
442
435
|
)
|
|
443
436
|
|
|
444
|
-
reportId = resolve_report_id(report,
|
|
437
|
+
reportId = resolve_report_id(report, workspace_id)
|
|
445
438
|
|
|
446
439
|
if target_workspace is None:
|
|
447
|
-
target_workspace =
|
|
440
|
+
target_workspace = workspace_name
|
|
448
441
|
target_workspace_id = workspace_id
|
|
449
442
|
else:
|
|
450
443
|
target_workspace_id = fabric.resolve_workspace_id(target_workspace)
|
|
451
444
|
|
|
452
445
|
if target_dataset is not None:
|
|
453
446
|
if target_dataset_workspace is None:
|
|
454
|
-
target_dataset_workspace =
|
|
447
|
+
target_dataset_workspace = workspace_name
|
|
455
448
|
target_dataset_id = resolve_dataset_id(target_dataset, target_dataset_workspace)
|
|
456
449
|
|
|
457
|
-
if report == cloned_report and
|
|
450
|
+
if report == cloned_report and workspace_name == target_workspace:
|
|
458
451
|
raise ValueError(
|
|
459
|
-
f"{icons.warning} The 'report' and 'cloned_report' parameters have the same value of '{report}. The 'workspace' and 'target_workspace' have the same value of '{
|
|
452
|
+
f"{icons.warning} The 'report' and 'cloned_report' parameters have the same value of '{report}. The 'workspace' and 'target_workspace' have the same value of '{workspace_name}'. Either the 'cloned_report' or the 'target_workspace' must be different from the original report."
|
|
460
453
|
)
|
|
461
454
|
|
|
462
455
|
client = fabric.PowerBIRestClient()
|
|
@@ -464,7 +457,7 @@ def clone_report(
|
|
|
464
457
|
request_body = {"name": cloned_report}
|
|
465
458
|
if target_dataset is not None:
|
|
466
459
|
request_body["targetModelId"] = target_dataset_id
|
|
467
|
-
if target_workspace !=
|
|
460
|
+
if target_workspace != workspace_name:
|
|
468
461
|
request_body["targetWorkspaceId"] = target_workspace_id
|
|
469
462
|
|
|
470
463
|
response = client.post(
|
|
@@ -478,7 +471,7 @@ def clone_report(
|
|
|
478
471
|
)
|
|
479
472
|
|
|
480
473
|
|
|
481
|
-
def launch_report(report: str, workspace: Optional[str] = None):
|
|
474
|
+
def launch_report(report: str, workspace: Optional[str | UUID] = None):
|
|
482
475
|
"""
|
|
483
476
|
Shows a Power BI report within a Fabric notebook.
|
|
484
477
|
|
|
@@ -486,8 +479,8 @@ def launch_report(report: str, workspace: Optional[str] = None):
|
|
|
486
479
|
----------
|
|
487
480
|
report : str
|
|
488
481
|
Name of the Power BI report.
|
|
489
|
-
workspace : str, default=None
|
|
490
|
-
The Fabric workspace name.
|
|
482
|
+
workspace : str | uuid.UUID, default=None
|
|
483
|
+
The Fabric workspace name or ID.
|
|
491
484
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
492
485
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
493
486
|
|
|
@@ -499,16 +492,14 @@ def launch_report(report: str, workspace: Optional[str] = None):
|
|
|
499
492
|
|
|
500
493
|
from sempy_labs import resolve_report_id
|
|
501
494
|
|
|
502
|
-
(
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
report = Report(group_id=workspace_id, report_id=reportId)
|
|
495
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
496
|
+
report_id = resolve_report_id(report, workspace_id)
|
|
497
|
+
report = Report(group_id=workspace_id, report_id=report_id)
|
|
507
498
|
|
|
508
499
|
return report
|
|
509
500
|
|
|
510
501
|
|
|
511
|
-
def list_report_pages(report: str, workspace: Optional[str] = None):
|
|
502
|
+
def list_report_pages(report: str, workspace: Optional[str | UUID] = None):
|
|
512
503
|
"""
|
|
513
504
|
Shows the properties of all pages within a Power BI report.
|
|
514
505
|
|
|
@@ -516,8 +507,8 @@ def list_report_pages(report: str, workspace: Optional[str] = None):
|
|
|
516
507
|
----------
|
|
517
508
|
report : str
|
|
518
509
|
Name of the Power BI report.
|
|
519
|
-
workspace : str, default=None
|
|
520
|
-
The Fabric workspace name.
|
|
510
|
+
workspace : str | uuid.UUID, default=None
|
|
511
|
+
The Fabric workspace name or ID.
|
|
521
512
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
522
513
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
523
514
|
|
|
@@ -527,15 +518,13 @@ def list_report_pages(report: str, workspace: Optional[str] = None):
|
|
|
527
518
|
A pandas dataframe showing the pages within a Power BI report and their properties.
|
|
528
519
|
"""
|
|
529
520
|
|
|
530
|
-
|
|
531
|
-
workspace_id = fabric.get_workspace_id()
|
|
532
|
-
workspace = fabric.resolve_workspace_name(workspace_id)
|
|
521
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
533
522
|
|
|
534
523
|
df = pd.DataFrame(
|
|
535
524
|
columns=["Page ID", "Page Name", "Hidden", "Width", "Height", "Visual Count"]
|
|
536
525
|
)
|
|
537
526
|
|
|
538
|
-
reportJson = get_report_json(report=report, workspace=
|
|
527
|
+
reportJson = get_report_json(report=report, workspace=workspace_id)
|
|
539
528
|
|
|
540
529
|
for section in reportJson["sections"]:
|
|
541
530
|
pageID = section.get("name")
|
|
@@ -572,7 +561,7 @@ def list_report_pages(report: str, workspace: Optional[str] = None):
|
|
|
572
561
|
return df
|
|
573
562
|
|
|
574
563
|
|
|
575
|
-
def list_report_visuals(report: str, workspace: Optional[str] = None):
|
|
564
|
+
def list_report_visuals(report: str, workspace: Optional[str | UUID] = None):
|
|
576
565
|
"""
|
|
577
566
|
Shows the properties of all visuals within a Power BI report.
|
|
578
567
|
|
|
@@ -580,8 +569,8 @@ def list_report_visuals(report: str, workspace: Optional[str] = None):
|
|
|
580
569
|
----------
|
|
581
570
|
report : str
|
|
582
571
|
Name of the Power BI report.
|
|
583
|
-
workspace : str, default=None
|
|
584
|
-
The Fabric workspace name.
|
|
572
|
+
workspace : str | uuid.UUID, default=None
|
|
573
|
+
The Fabric workspace name or ID.
|
|
585
574
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
586
575
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
587
576
|
|
|
@@ -591,11 +580,9 @@ def list_report_visuals(report: str, workspace: Optional[str] = None):
|
|
|
591
580
|
A pandas dataframe showing the visuals within a Power BI report and their properties.
|
|
592
581
|
"""
|
|
593
582
|
|
|
594
|
-
|
|
595
|
-
workspace_id = fabric.get_workspace_id()
|
|
596
|
-
workspace = fabric.resolve_workspace_name(workspace_id)
|
|
583
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
597
584
|
|
|
598
|
-
reportJson = get_report_json(report=report, workspace=
|
|
585
|
+
reportJson = get_report_json(report=report, workspace=workspace_id)
|
|
599
586
|
|
|
600
587
|
df = pd.DataFrame(columns=["Page Name", "Page ID", "Visual ID", "Title"])
|
|
601
588
|
|
|
@@ -627,7 +614,7 @@ def list_report_visuals(report: str, workspace: Optional[str] = None):
|
|
|
627
614
|
return df
|
|
628
615
|
|
|
629
616
|
|
|
630
|
-
def list_report_bookmarks(report: str, workspace: Optional[str] = None):
|
|
617
|
+
def list_report_bookmarks(report: str, workspace: Optional[str | UUID] = None):
|
|
631
618
|
"""
|
|
632
619
|
Shows the properties of all bookmarks within a Power BI report.
|
|
633
620
|
|
|
@@ -635,8 +622,8 @@ def list_report_bookmarks(report: str, workspace: Optional[str] = None):
|
|
|
635
622
|
----------
|
|
636
623
|
report : str
|
|
637
624
|
Name of the Power BI report.
|
|
638
|
-
workspace : str, default=None
|
|
639
|
-
The Fabric workspace name.
|
|
625
|
+
workspace : str | uuid.UUID, default=None
|
|
626
|
+
The Fabric workspace name or ID.
|
|
640
627
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
641
628
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
642
629
|
|
|
@@ -646,9 +633,7 @@ def list_report_bookmarks(report: str, workspace: Optional[str] = None):
|
|
|
646
633
|
A pandas dataframe showing the bookmarks within a Power BI report and their properties.
|
|
647
634
|
"""
|
|
648
635
|
|
|
649
|
-
|
|
650
|
-
workspace_id = fabric.get_workspace_id()
|
|
651
|
-
workspace = fabric.resolve_workspace_name(workspace_id)
|
|
636
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
652
637
|
|
|
653
638
|
df = pd.DataFrame(
|
|
654
639
|
columns=[
|
|
@@ -660,7 +645,7 @@ def list_report_bookmarks(report: str, workspace: Optional[str] = None):
|
|
|
660
645
|
]
|
|
661
646
|
)
|
|
662
647
|
|
|
663
|
-
reportJson = get_report_json(report=report, workspace=
|
|
648
|
+
reportJson = get_report_json(report=report, workspace=workspace_id)
|
|
664
649
|
reportConfig = reportJson["config"]
|
|
665
650
|
reportConfigJson = json.loads(reportConfig)
|
|
666
651
|
|
|
@@ -693,7 +678,7 @@ def list_report_bookmarks(report: str, workspace: Optional[str] = None):
|
|
|
693
678
|
}
|
|
694
679
|
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
695
680
|
|
|
696
|
-
listPages = list_report_pages(report=report, workspace=
|
|
681
|
+
listPages = list_report_pages(report=report, workspace=workspace_id)
|
|
697
682
|
|
|
698
683
|
df = pd.merge(df, listPages[["Page ID", "Page Name"]], on="Page ID", how="left")
|
|
699
684
|
df = df[
|
|
@@ -711,13 +696,15 @@ def list_report_bookmarks(report: str, workspace: Optional[str] = None):
|
|
|
711
696
|
|
|
712
697
|
except Exception:
|
|
713
698
|
print(
|
|
714
|
-
f"The '{report}' report within the '{
|
|
699
|
+
f"The '{report}' report within the '{workspace_name}' workspace has no bookmarks."
|
|
715
700
|
)
|
|
716
701
|
|
|
717
702
|
|
|
718
703
|
@log
|
|
719
704
|
def translate_report_titles(
|
|
720
|
-
report: str,
|
|
705
|
+
report: str,
|
|
706
|
+
languages: Union[str, List[str]],
|
|
707
|
+
workspace: Optional[str | UUID] = None,
|
|
721
708
|
):
|
|
722
709
|
"""
|
|
723
710
|
Dynamically generates new Power BI reports which have report titles translated into the specified language(s).
|
|
@@ -728,22 +715,24 @@ def translate_report_titles(
|
|
|
728
715
|
Name of the Power BI report.
|
|
729
716
|
languages : str, List[str]
|
|
730
717
|
The language code(s) in which to translate the report titles.
|
|
731
|
-
workspace : str, default=None
|
|
732
|
-
The Fabric workspace name.
|
|
718
|
+
workspace : str | uuid.UUID, default=None
|
|
719
|
+
The Fabric workspace name or ID.
|
|
733
720
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
734
721
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
735
722
|
"""
|
|
736
723
|
from synapse.ml.services import Translate
|
|
737
724
|
from pyspark.sql import SparkSession
|
|
738
725
|
|
|
726
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
727
|
+
|
|
739
728
|
if isinstance(languages, str):
|
|
740
729
|
languages = [languages]
|
|
741
730
|
|
|
742
731
|
for lang in languages:
|
|
743
732
|
language_validate(lang)
|
|
744
733
|
|
|
745
|
-
reportJson = get_report_json(report=report, workspace=
|
|
746
|
-
dfV = list_report_visuals(report=report, workspace=
|
|
734
|
+
reportJson = get_report_json(report=report, workspace=workspace_id)
|
|
735
|
+
dfV = list_report_visuals(report=report, workspace=workspace_id)
|
|
747
736
|
spark = SparkSession.builder.getOrCreate()
|
|
748
737
|
df = spark.createDataFrame(dfV)
|
|
749
738
|
columnToTranslate = "Title"
|
|
@@ -771,7 +760,7 @@ def translate_report_titles(
|
|
|
771
760
|
language = language_validate(lang)
|
|
772
761
|
clonedReportName = f"{report}_{language}"
|
|
773
762
|
|
|
774
|
-
dfRep = fabric.list_reports(workspace=
|
|
763
|
+
dfRep = fabric.list_reports(workspace=workspace_id)
|
|
775
764
|
dfRep_filt = dfRep[
|
|
776
765
|
(dfRep["Name"] == clonedReportName)
|
|
777
766
|
& (dfRep["Report Type"] == "PowerBIReport")
|
|
@@ -779,14 +768,14 @@ def translate_report_titles(
|
|
|
779
768
|
|
|
780
769
|
if len(dfRep_filt) > 0:
|
|
781
770
|
print(
|
|
782
|
-
f"{icons.yellow_dot} The '{clonedReportName}' report already exists in the '{
|
|
771
|
+
f"{icons.yellow_dot} The '{clonedReportName}' report already exists in the '{workspace_name} workspace."
|
|
783
772
|
)
|
|
784
773
|
else:
|
|
785
774
|
clone_report(
|
|
786
|
-
report=report, cloned_report=clonedReportName, workspace=
|
|
775
|
+
report=report, cloned_report=clonedReportName, workspace=workspace_id
|
|
787
776
|
)
|
|
788
777
|
print(
|
|
789
|
-
f"{icons.green_dot} The '{clonedReportName}' report has been created via clone in the '{
|
|
778
|
+
f"{icons.green_dot} The '{clonedReportName}' report has been created via clone in the '{workspace_name} workspace."
|
|
790
779
|
)
|
|
791
780
|
|
|
792
781
|
rptJsonTr = copy.deepcopy(reportJson)
|
|
@@ -816,8 +805,8 @@ def translate_report_titles(
|
|
|
816
805
|
|
|
817
806
|
# Post updated report json file to cloned report
|
|
818
807
|
update_report_from_reportjson(
|
|
819
|
-
report=clonedReportName, report_json=rptJsonTr, workspace=
|
|
808
|
+
report=clonedReportName, report_json=rptJsonTr, workspace=workspace_id
|
|
820
809
|
)
|
|
821
810
|
print(
|
|
822
|
-
f"{icons.green_dot} The visual titles within the '{clonedReportName}' report within the '{
|
|
811
|
+
f"{icons.green_dot} The visual titles within the '{clonedReportName}' report within the '{workspace_name}' have been translated into '{language}' accordingly."
|
|
823
812
|
)
|
|
@@ -5,6 +5,10 @@ import re
|
|
|
5
5
|
import base64
|
|
6
6
|
import json
|
|
7
7
|
import requests
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
from sempy_labs._helper_functions import (
|
|
10
|
+
resolve_workspace_name_and_id,
|
|
11
|
+
)
|
|
8
12
|
|
|
9
13
|
|
|
10
14
|
vis_type_mapping = {
|
|
@@ -66,16 +70,16 @@ page_type_mapping = {
|
|
|
66
70
|
page_types = ["Tooltip", "Letter", "4:3", "16:9"]
|
|
67
71
|
|
|
68
72
|
|
|
69
|
-
def get_web_url(report: str, workspace: Optional[str] = None):
|
|
73
|
+
def get_web_url(report: str, workspace: Optional[str | UUID] = None):
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
72
76
|
|
|
73
|
-
dfR = fabric.list_reports(workspace=
|
|
77
|
+
dfR = fabric.list_reports(workspace=workspace_id)
|
|
74
78
|
dfR_filt = dfR[dfR["Name"] == report]
|
|
75
79
|
|
|
76
80
|
if len(dfR_filt) == 0:
|
|
77
81
|
raise ValueError(
|
|
78
|
-
f"{icons.red_dot} The '{report}' report does not exist within the '{
|
|
82
|
+
f"{icons.red_dot} The '{report}' report does not exist within the '{workspace_name}' workspace."
|
|
79
83
|
)
|
|
80
84
|
web_url = dfR_filt["Web Url"].iloc[0]
|
|
81
85
|
|
|
@@ -3,13 +3,16 @@ from typing import Optional
|
|
|
3
3
|
import pandas as pd
|
|
4
4
|
from sempy_labs._helper_functions import (
|
|
5
5
|
format_dax_object_name,
|
|
6
|
+
resolve_workspace_name_and_id,
|
|
7
|
+
resolve_dataset_name_and_id,
|
|
6
8
|
)
|
|
7
9
|
from sempy_labs.report._reportwrapper import ReportWrapper
|
|
8
10
|
from sempy_labs._list_functions import list_reports_using_semantic_model
|
|
11
|
+
from uuid import UUID
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
def list_unused_objects_in_reports(
|
|
12
|
-
dataset: str, workspace: Optional[str] = None
|
|
15
|
+
dataset: str | UUID, workspace: Optional[str | UUID] = None
|
|
13
16
|
) -> pd.DataFrame:
|
|
14
17
|
"""
|
|
15
18
|
Shows a list of all columns in the semantic model which are not used in any related Power BI reports (including dependencies).
|
|
@@ -17,10 +20,10 @@ def list_unused_objects_in_reports(
|
|
|
17
20
|
|
|
18
21
|
Parameters
|
|
19
22
|
----------
|
|
20
|
-
dataset : str
|
|
21
|
-
Name of the semantic model.
|
|
22
|
-
workspace : str, default=None
|
|
23
|
-
The Fabric workspace name.
|
|
23
|
+
dataset : str | uuid.UUID
|
|
24
|
+
Name or ID of the semantic model.
|
|
25
|
+
workspace : str | uuid.UUID, default=None
|
|
26
|
+
The Fabric workspace name or ID.
|
|
24
27
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
25
28
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
26
29
|
|
|
@@ -32,7 +35,12 @@ def list_unused_objects_in_reports(
|
|
|
32
35
|
|
|
33
36
|
# TODO: what about relationships/RLS?
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
39
|
+
(dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
|
|
40
|
+
|
|
41
|
+
dfR = _list_all_report_semantic_model_objects(
|
|
42
|
+
dataset=dataset_id, workspace=workspace_id
|
|
43
|
+
)
|
|
36
44
|
dfR_filt = (
|
|
37
45
|
dfR[dfR["Object Type"] == "Column"][["Table Name", "Object Name"]]
|
|
38
46
|
.drop_duplicates()
|
|
@@ -42,7 +50,7 @@ def list_unused_objects_in_reports(
|
|
|
42
50
|
dfR_filt["Table Name"], dfR_filt["Object Name"]
|
|
43
51
|
)
|
|
44
52
|
|
|
45
|
-
dfC = fabric.list_columns(dataset=
|
|
53
|
+
dfC = fabric.list_columns(dataset=dataset_id, workspace=workspace_id)
|
|
46
54
|
dfC["Column Object"] = format_dax_object_name(dfC["Table Name"], dfC["Column Name"])
|
|
47
55
|
|
|
48
56
|
df = dfC[~(dfC["Column Object"].isin(dfR_filt["Column Object"].values))]
|
|
@@ -52,7 +60,7 @@ def list_unused_objects_in_reports(
|
|
|
52
60
|
|
|
53
61
|
|
|
54
62
|
def _list_all_report_semantic_model_objects(
|
|
55
|
-
dataset: str, workspace: Optional[str] = None
|
|
63
|
+
dataset: str | UUID, workspace: Optional[str | UUID] = None
|
|
56
64
|
) -> pd.DataFrame:
|
|
57
65
|
"""
|
|
58
66
|
Shows a unique list of all semantic model objects (columns, measures, hierarchies) which are used in all reports which leverage the semantic model.
|
|
@@ -60,10 +68,10 @@ def _list_all_report_semantic_model_objects(
|
|
|
60
68
|
|
|
61
69
|
Parameters
|
|
62
70
|
----------
|
|
63
|
-
dataset : str
|
|
64
|
-
Name of the semantic model.
|
|
65
|
-
workspace : str, default=None
|
|
66
|
-
The Fabric workspace name.
|
|
71
|
+
dataset : str | uuid.UUID
|
|
72
|
+
Name or ID of the semantic model.
|
|
73
|
+
workspace : str | uuid.UUID, default=None
|
|
74
|
+
The Fabric workspace name or ID.
|
|
67
75
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
68
76
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
69
77
|
|
|
@@ -73,7 +81,10 @@ def _list_all_report_semantic_model_objects(
|
|
|
73
81
|
A pandas dataframe.
|
|
74
82
|
"""
|
|
75
83
|
|
|
76
|
-
|
|
84
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
85
|
+
(dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
|
|
86
|
+
|
|
87
|
+
dfR = list_reports_using_semantic_model(dataset=dataset_id, workspace=workspace_id)
|
|
77
88
|
dfs = []
|
|
78
89
|
|
|
79
90
|
for _, r in dfR.iterrows():
|