semantic-link-labs 0.8.6__py3-none-any.whl → 0.8.7__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.6.dist-info → semantic_link_labs-0.8.7.dist-info}/METADATA +14 -6
- {semantic_link_labs-0.8.6.dist-info → semantic_link_labs-0.8.7.dist-info}/RECORD +34 -28
- {semantic_link_labs-0.8.6.dist-info → semantic_link_labs-0.8.7.dist-info}/WHEEL +1 -1
- sempy_labs/__init__.py +37 -6
- sempy_labs/_authentication.py +108 -0
- sempy_labs/_connections.py +355 -176
- sempy_labs/_dataflows.py +0 -1
- sempy_labs/_gateways.py +439 -0
- sempy_labs/_generate_semantic_model.py +51 -30
- sempy_labs/_git.py +13 -5
- sempy_labs/_helper_functions.py +14 -3
- sempy_labs/_list_functions.py +1 -1
- sempy_labs/_model_auto_build.py +4 -2
- sempy_labs/_model_bpa.py +2 -15
- sempy_labs/_model_bpa_bulk.py +4 -2
- sempy_labs/_refresh_semantic_model.py +6 -0
- sempy_labs/admin/__init__.py +19 -9
- sempy_labs/admin/_basic_functions.py +475 -548
- sempy_labs/admin/_external_data_share.py +97 -0
- sempy_labs/admin/_git.py +69 -0
- sempy_labs/admin/_items.py +264 -0
- sempy_labs/admin/_scanner.py +104 -0
- sempy_labs/directlake/_dl_helper.py +6 -2
- sempy_labs/directlake/_get_shared_expression.py +5 -35
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +3 -2
- sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +4 -2
- sempy_labs/report/_generate_report.py +10 -4
- sempy_labs/report/_report_bpa.py +1 -0
- sempy_labs/report/_report_helper.py +58 -0
- sempy_labs/report/_report_list_functions.py +2 -0
- sempy_labs/report/_reportwrapper.py +358 -175
- sempy_labs/tom/_model.py +1 -0
- {semantic_link_labs-0.8.6.dist-info → semantic_link_labs-0.8.7.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.8.6.dist-info → semantic_link_labs-0.8.7.dist-info}/top_level.txt +0 -0
|
@@ -7,11 +7,10 @@ from sempy_labs._helper_functions import (
|
|
|
7
7
|
_extract_json,
|
|
8
8
|
_add_part,
|
|
9
9
|
lro,
|
|
10
|
-
|
|
10
|
+
_decode_b64,
|
|
11
11
|
)
|
|
12
12
|
from typing import Optional, List
|
|
13
13
|
import pandas as pd
|
|
14
|
-
import re
|
|
15
14
|
import json
|
|
16
15
|
import base64
|
|
17
16
|
from uuid import UUID
|
|
@@ -24,6 +23,25 @@ import warnings
|
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
class ReportWrapper:
|
|
26
|
+
"""
|
|
27
|
+
Connects to a Power BI report and retrieves its definition.
|
|
28
|
+
|
|
29
|
+
The ReportWrapper and all functions which depend on it require the report to be in the `PBIR <https://powerbi.microsoft.com/blog/power-bi-enhanced-report-format-pbir-in-power-bi-desktop-developer-mode-preview>`_ format.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
report : str
|
|
34
|
+
The name of the report.
|
|
35
|
+
workspace : str
|
|
36
|
+
The name of the workspace in which the report resides.
|
|
37
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
38
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
pandas.DataFrame
|
|
43
|
+
A pandas dataframe containing the report metadata definition files.
|
|
44
|
+
"""
|
|
27
45
|
|
|
28
46
|
_report: str
|
|
29
47
|
_workspace: str
|
|
@@ -34,6 +52,25 @@ class ReportWrapper:
|
|
|
34
52
|
report: str,
|
|
35
53
|
workspace: Optional[str] = None,
|
|
36
54
|
):
|
|
55
|
+
"""
|
|
56
|
+
Connects to a Power BI report and retrieves its definition.
|
|
57
|
+
|
|
58
|
+
The ReportWrapper and all functions which depend on it require the report to be in the `PBIR <https://powerbi.microsoft.com/blog/power-bi-enhanced-report-format-pbir-in-power-bi-desktop-developer-mode-preview>`_ format.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
report : str
|
|
63
|
+
The name of the report.
|
|
64
|
+
workspace : str
|
|
65
|
+
The name of the workspace in which the report resides.
|
|
66
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
67
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
pandas.DataFrame
|
|
72
|
+
A pandas dataframe containing the report metadata definition files.
|
|
73
|
+
"""
|
|
37
74
|
|
|
38
75
|
from sempy_labs.report import get_report_definition
|
|
39
76
|
|
|
@@ -85,6 +122,22 @@ class ReportWrapper:
|
|
|
85
122
|
)
|
|
86
123
|
return dataframe
|
|
87
124
|
|
|
125
|
+
def _update_single_file(self, file_name: str, new_payload):
|
|
126
|
+
"""
|
|
127
|
+
Updates a single file within the PBIR structure
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
request_body = {"definition": {"parts": []}}
|
|
131
|
+
for _, r in self.rdef.iterrows():
|
|
132
|
+
path = r["path"]
|
|
133
|
+
payload = r["payload"]
|
|
134
|
+
if path == file_name:
|
|
135
|
+
_add_part(request_body, path=path, payload=new_payload)
|
|
136
|
+
else:
|
|
137
|
+
_add_part(request_body, path=path, payload=payload)
|
|
138
|
+
|
|
139
|
+
self.update_report(request_body)
|
|
140
|
+
|
|
88
141
|
def update_report(self, request_body: dict):
|
|
89
142
|
|
|
90
143
|
client = fabric.FabricRestClient()
|
|
@@ -692,6 +745,7 @@ class ReportWrapper:
|
|
|
692
745
|
custom_visuals = rptJson.get("publicCustomVisuals", [])
|
|
693
746
|
page_mapping, visual_mapping = helper.visual_page_mapping(self)
|
|
694
747
|
helper.populate_custom_visual_display_names()
|
|
748
|
+
agg_type_map = helper._get_agg_type_mapping()
|
|
695
749
|
|
|
696
750
|
def contains_key(data, keys_to_check):
|
|
697
751
|
matches = parse("$..*").find(data)
|
|
@@ -738,21 +792,36 @@ class ReportWrapper:
|
|
|
738
792
|
|
|
739
793
|
# Title
|
|
740
794
|
matches = parse(
|
|
741
|
-
"$.visual.visualContainerObjects.title[0].properties.text.expr
|
|
795
|
+
"$.visual.visualContainerObjects.title[0].properties.text.expr"
|
|
742
796
|
).find(visual_json)
|
|
743
|
-
title = matches[0].value[1:-1] if matches else ""
|
|
797
|
+
# title = matches[0].value[1:-1] if matches else ""
|
|
798
|
+
title = (
|
|
799
|
+
helper._get_expression(matches[0].value, agg_type_map)
|
|
800
|
+
if matches
|
|
801
|
+
else ""
|
|
802
|
+
)
|
|
744
803
|
|
|
745
804
|
# SubTitle
|
|
746
805
|
matches = parse(
|
|
747
|
-
"$.visual.visualContainerObjects.subTitle[0].properties.text.expr
|
|
806
|
+
"$.visual.visualContainerObjects.subTitle[0].properties.text.expr"
|
|
748
807
|
).find(visual_json)
|
|
749
|
-
sub_title = matches[0].value[1:-1] if matches else ""
|
|
808
|
+
# sub_title = matches[0].value[1:-1] if matches else ""
|
|
809
|
+
sub_title = (
|
|
810
|
+
helper._get_expression(matches[0].value, agg_type_map)
|
|
811
|
+
if matches
|
|
812
|
+
else ""
|
|
813
|
+
)
|
|
750
814
|
|
|
751
815
|
# Alt Text
|
|
752
816
|
matches = parse(
|
|
753
|
-
"$.visual.visualContainerObjects.general[0].properties.altText.expr
|
|
817
|
+
"$.visual.visualContainerObjects.general[0].properties.altText.expr"
|
|
754
818
|
).find(visual_json)
|
|
755
|
-
alt_text = matches[0].value[1:-1] if matches else ""
|
|
819
|
+
# alt_text = matches[0].value[1:-1] if matches else ""
|
|
820
|
+
alt_text = (
|
|
821
|
+
helper._get_expression(matches[0].value, agg_type_map)
|
|
822
|
+
if matches
|
|
823
|
+
else ""
|
|
824
|
+
)
|
|
756
825
|
|
|
757
826
|
# Show items with no data
|
|
758
827
|
def find_show_all_with_jsonpath(obj):
|
|
@@ -1296,6 +1365,71 @@ class ReportWrapper:
|
|
|
1296
1365
|
|
|
1297
1366
|
return df
|
|
1298
1367
|
|
|
1368
|
+
def _list_annotations(self) -> pd.DataFrame:
|
|
1369
|
+
"""
|
|
1370
|
+
Shows a list of annotations in the report.
|
|
1371
|
+
|
|
1372
|
+
Returns
|
|
1373
|
+
-------
|
|
1374
|
+
pandas.DataFrame
|
|
1375
|
+
A pandas dataframe showing a list of report, page and visual annotations in the report.
|
|
1376
|
+
"""
|
|
1377
|
+
|
|
1378
|
+
df = pd.DataFrame(
|
|
1379
|
+
columns=["Type", "Object Name", "Annotation Name", "Annotation Value"]
|
|
1380
|
+
)
|
|
1381
|
+
|
|
1382
|
+
page_mapping, visual_mapping = helper.visual_page_mapping(self)
|
|
1383
|
+
for _, r in self.rdef.iterrows():
|
|
1384
|
+
payload = r["payload"]
|
|
1385
|
+
path = r["path"]
|
|
1386
|
+
if path == "definition/report.json":
|
|
1387
|
+
file = _decode_b64(payload)
|
|
1388
|
+
json_file = json.loads(file)
|
|
1389
|
+
if "annotations" in json_file:
|
|
1390
|
+
for ann in json_file["annotations"]:
|
|
1391
|
+
new_data = {
|
|
1392
|
+
"Type": "Report",
|
|
1393
|
+
"Object Name": self._report,
|
|
1394
|
+
"Annotation Name": ann.get("name"),
|
|
1395
|
+
"Annotation Value": ann.get("value"),
|
|
1396
|
+
}
|
|
1397
|
+
df = pd.concat(
|
|
1398
|
+
[df, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
1399
|
+
)
|
|
1400
|
+
elif path.endswith("/page.json"):
|
|
1401
|
+
file = _decode_b64(payload)
|
|
1402
|
+
json_file = json.loads(file)
|
|
1403
|
+
if "annotations" in json_file:
|
|
1404
|
+
for ann in json_file["annotations"]:
|
|
1405
|
+
new_data = {
|
|
1406
|
+
"Type": "Page",
|
|
1407
|
+
"Object Name": json_file.get("displayName"),
|
|
1408
|
+
"Annotation Name": ann.get("name"),
|
|
1409
|
+
"Annotation Value": ann.get("value"),
|
|
1410
|
+
}
|
|
1411
|
+
df = pd.concat(
|
|
1412
|
+
[df, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
1413
|
+
)
|
|
1414
|
+
elif path.endswith("/visual.json"):
|
|
1415
|
+
file = _decode_b64(payload)
|
|
1416
|
+
json_file = json.loads(file)
|
|
1417
|
+
page_display = visual_mapping.get(path)[1]
|
|
1418
|
+
visual_name = json_file.get("name")
|
|
1419
|
+
if "annotations" in json_file:
|
|
1420
|
+
for ann in json_file["annotations"]:
|
|
1421
|
+
new_data = {
|
|
1422
|
+
"Type": "Visual",
|
|
1423
|
+
"Object Name": f"'{page_display}'[{visual_name}]",
|
|
1424
|
+
"Annotation Name": ann.get("name"),
|
|
1425
|
+
"Annotation Value": ann.get("value"),
|
|
1426
|
+
}
|
|
1427
|
+
df = pd.concat(
|
|
1428
|
+
[df, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
1429
|
+
)
|
|
1430
|
+
|
|
1431
|
+
return df
|
|
1432
|
+
|
|
1299
1433
|
# Automation functions
|
|
1300
1434
|
def set_theme(self, theme_file_path: str):
|
|
1301
1435
|
"""
|
|
@@ -1414,41 +1548,40 @@ class ReportWrapper:
|
|
|
1414
1548
|
"""
|
|
1415
1549
|
|
|
1416
1550
|
pages_file = "definition/pages/pages.json"
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
rd = self.rdef
|
|
1420
|
-
page_id, page_display, file_path = helper.resolve_page_name(
|
|
1551
|
+
page_id, page_display_name, file_path = helper.resolve_page_name(
|
|
1421
1552
|
self, page_name=page_name
|
|
1422
1553
|
)
|
|
1423
|
-
for _, r in rd.iterrows():
|
|
1424
|
-
path = r["path"]
|
|
1425
|
-
file_payload = r["payload"]
|
|
1426
|
-
if path != pages_file:
|
|
1427
|
-
_add_part(request_body, path, file_payload)
|
|
1428
1554
|
|
|
1429
|
-
pagePath =
|
|
1555
|
+
pagePath = self.rdef[self.rdef["path"] == pages_file]
|
|
1430
1556
|
payload = pagePath["payload"].iloc[0]
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
file_payload = _conv_b64(
|
|
1557
|
+
page_file = _decode_b64(payload)
|
|
1558
|
+
json_file = json.loads(page_file)
|
|
1559
|
+
json_file["activePageName"] = page_id
|
|
1560
|
+
file_payload = _conv_b64(json_file)
|
|
1435
1561
|
|
|
1436
|
-
|
|
1562
|
+
self._update_single_file(file_name=pages_file, new_payload=file_payload)
|
|
1437
1563
|
|
|
1438
|
-
self.update_report(request_body=request_body)
|
|
1439
1564
|
print(
|
|
1440
|
-
f"{icons.green_dot} The '{
|
|
1565
|
+
f"{icons.green_dot} The '{page_display_name}' page has been set as the active page in the '{self._report}' report within the '{self._workspace}' workspace."
|
|
1441
1566
|
)
|
|
1442
1567
|
|
|
1443
1568
|
def set_page_type(self, page_name: str, page_type: str):
|
|
1569
|
+
"""
|
|
1570
|
+
Changes the page type of a report page.
|
|
1571
|
+
|
|
1572
|
+
Parameters
|
|
1573
|
+
----------
|
|
1574
|
+
page_name : str
|
|
1575
|
+
Name or display name of the report page.
|
|
1576
|
+
page_type : str
|
|
1577
|
+
The page type. Valid page types: 'Tooltip', 'Letter', '4:3', '16:9'.
|
|
1578
|
+
"""
|
|
1444
1579
|
|
|
1445
1580
|
if page_type not in helper.page_types:
|
|
1446
1581
|
raise ValueError(
|
|
1447
1582
|
f"{icons.red_dot} Invalid page type. Valid options: {helper.page_types}."
|
|
1448
1583
|
)
|
|
1449
1584
|
|
|
1450
|
-
request_body = {"definition": {"parts": []}}
|
|
1451
|
-
|
|
1452
1585
|
letter_key = next(
|
|
1453
1586
|
(
|
|
1454
1587
|
key
|
|
@@ -1461,30 +1594,24 @@ class ReportWrapper:
|
|
|
1461
1594
|
width, height = letter_key
|
|
1462
1595
|
else:
|
|
1463
1596
|
raise ValueError(
|
|
1464
|
-
"Invalid page_type parameter. Valid options: ['Tooltip', 'Letter', '4:3', '16:9']."
|
|
1597
|
+
f"{icons.red_dot} Invalid page_type parameter. Valid options: ['Tooltip', 'Letter', '4:3', '16:9']."
|
|
1465
1598
|
)
|
|
1466
1599
|
|
|
1467
|
-
|
|
1468
|
-
page_id, page_display, file_path = helper.resolve_page_name(
|
|
1600
|
+
page_id, page_display_name, file_path = helper.resolve_page_name(
|
|
1469
1601
|
self, page_name=page_name
|
|
1470
1602
|
)
|
|
1471
|
-
rd_filt =
|
|
1603
|
+
rd_filt = self.rdef[self.rdef["path"] == file_path]
|
|
1472
1604
|
payload = rd_filt["payload"].iloc[0]
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
file_payload = _conv_b64(pageJson)
|
|
1479
|
-
_add_part(request_body, file_path, file_payload)
|
|
1605
|
+
page_file = _decode_b64(payload)
|
|
1606
|
+
json_file = json.loads(page_file)
|
|
1607
|
+
json_file["width"] = width
|
|
1608
|
+
json_file["height"] = height
|
|
1609
|
+
file_payload = _conv_b64(json_file)
|
|
1480
1610
|
|
|
1481
|
-
|
|
1482
|
-
if r["path"] != file_path:
|
|
1483
|
-
_add_part(request_body, r["path"], r["payload"])
|
|
1611
|
+
self._update_single_file(file_name=file_path, new_payload=file_payload)
|
|
1484
1612
|
|
|
1485
|
-
self.update_report(request_body=request_body)
|
|
1486
1613
|
print(
|
|
1487
|
-
f"The '{
|
|
1614
|
+
f"{icons.green_dot} The '{page_display_name}' page has been updated to the '{page_type}' page type."
|
|
1488
1615
|
)
|
|
1489
1616
|
|
|
1490
1617
|
def remove_unnecessary_custom_visuals(self):
|
|
@@ -1632,31 +1759,27 @@ class ReportWrapper:
|
|
|
1632
1759
|
If set to False, makes the report page visible.
|
|
1633
1760
|
"""
|
|
1634
1761
|
|
|
1635
|
-
|
|
1636
|
-
page_id, page_display, file_path = helper.resolve_page_name(
|
|
1762
|
+
page_id, page_display_name, file_path = helper.resolve_page_name(
|
|
1637
1763
|
self, page_name=page_name
|
|
1638
1764
|
)
|
|
1639
1765
|
visibility = "visible" if hidden is False else "hidden"
|
|
1640
1766
|
|
|
1641
|
-
|
|
1767
|
+
rd_filt = self.rdef[self.rdef["path"] == file_path]
|
|
1768
|
+
payload = rd_filt["payload"].iloc[0]
|
|
1769
|
+
obj_file = _decode_b64(payload)
|
|
1770
|
+
obj_json = json.loads(obj_file)
|
|
1771
|
+
if hidden:
|
|
1772
|
+
obj_json["visibility"] = "HiddenInViewMode"
|
|
1773
|
+
else:
|
|
1774
|
+
if "visibility" in obj_json:
|
|
1775
|
+
del obj_json["visibility"]
|
|
1776
|
+
new_payload = _conv_b64(obj_json)
|
|
1642
1777
|
|
|
1643
|
-
|
|
1644
|
-
path = r["path"]
|
|
1645
|
-
payload = r["payload"]
|
|
1646
|
-
if path == file_path:
|
|
1647
|
-
obj_file = base64.b64decode(payload).decode("utf-8")
|
|
1648
|
-
obj_json = json.loads(obj_file)
|
|
1649
|
-
if hidden:
|
|
1650
|
-
obj_json["visibility"] = "HiddenInViewMode"
|
|
1651
|
-
else:
|
|
1652
|
-
if "visibility" in obj_json:
|
|
1653
|
-
del obj_json["visibility"]
|
|
1654
|
-
_add_part(request_body, path, _conv_b64(obj_json))
|
|
1655
|
-
else:
|
|
1656
|
-
_add_part(request_body, path, payload)
|
|
1778
|
+
self._update_single_file(file_name=file_path, new_payload=new_payload)
|
|
1657
1779
|
|
|
1658
|
-
|
|
1659
|
-
|
|
1780
|
+
print(
|
|
1781
|
+
f"{icons.green_dot} The '{page_display_name}' page has been set to {visibility}."
|
|
1782
|
+
)
|
|
1660
1783
|
|
|
1661
1784
|
def hide_tooltip_drillthrough_pages(self):
|
|
1662
1785
|
"""
|
|
@@ -1712,142 +1835,202 @@ class ReportWrapper:
|
|
|
1712
1835
|
f"{icons.green_dot} Show items with data has been disabled for all visuals in the '{self._report}' report within the '{self._workspace}' workspace."
|
|
1713
1836
|
)
|
|
1714
1837
|
|
|
1715
|
-
|
|
1838
|
+
# Set Annotations
|
|
1839
|
+
def __set_annotation(self, json_file: dict, name: str, value: str) -> dict:
|
|
1716
1840
|
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1841
|
+
if "annotations" in json_file:
|
|
1842
|
+
if any(
|
|
1843
|
+
annotation["name"] == name for annotation in json_file["annotations"]
|
|
1844
|
+
):
|
|
1845
|
+
for annotation in json_file["annotations"]:
|
|
1846
|
+
if annotation["name"] == name:
|
|
1847
|
+
annotation["value"] = value
|
|
1848
|
+
break
|
|
1849
|
+
else:
|
|
1850
|
+
json_file["annotations"].append({"name": name, "value": value})
|
|
1851
|
+
else:
|
|
1852
|
+
json_file["annotations"] = []
|
|
1853
|
+
json_file["annotations"].append({"name": name, "value": value})
|
|
1723
1854
|
|
|
1724
|
-
|
|
1855
|
+
return json_file
|
|
1856
|
+
|
|
1857
|
+
def _set_annotation(
|
|
1858
|
+
self,
|
|
1859
|
+
annotation_name: str,
|
|
1860
|
+
annotation_value: str,
|
|
1861
|
+
page_name: Optional[str] = None,
|
|
1862
|
+
visual_name: Optional[str] = None,
|
|
1863
|
+
):
|
|
1864
|
+
"""
|
|
1865
|
+
Sets an annotation on the report/page/visual. If the annotation already exists, the annotation value is updated.
|
|
1866
|
+
In order to set a report annotation, leave page_name=None, visual_name=None.
|
|
1867
|
+
In order to set a page annotation, leave visual_annotation=None.
|
|
1868
|
+
In order to set a visual annotation, set all parameters.
|
|
1725
1869
|
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1870
|
+
Parameters
|
|
1871
|
+
----------
|
|
1872
|
+
annotation_name : str
|
|
1873
|
+
Name of the annotation.
|
|
1874
|
+
annotation_value : str
|
|
1875
|
+
Value of the annotation.
|
|
1876
|
+
page_name : str, default=None
|
|
1877
|
+
The page name or page display name.
|
|
1878
|
+
Set this annotation when setting an annotation on a page or visual.
|
|
1879
|
+
visual_name : str, default=None
|
|
1880
|
+
The visual name.
|
|
1881
|
+
Set this property when setting an annotation on a visual.
|
|
1882
|
+
"""
|
|
1883
|
+
|
|
1884
|
+
if page_name is None and visual_name is None:
|
|
1885
|
+
file_path = "definition/report.json"
|
|
1886
|
+
elif page_name is not None and visual_name is None:
|
|
1887
|
+
page_id, page_display, file_path = helper.resolve_page_name(
|
|
1888
|
+
self, page_name=page_name
|
|
1732
1889
|
)
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
elif object_type == "Visual":
|
|
1738
|
-
pattern = r"'([^']+)'\[([^]]+)\]"
|
|
1739
|
-
match = re.search(pattern, object_name)
|
|
1740
|
-
if match:
|
|
1741
|
-
p_name = match.group(1)
|
|
1742
|
-
v_name = match.group(2)
|
|
1743
|
-
else:
|
|
1744
|
-
raise ValueError(
|
|
1745
|
-
"Invalid page/visual name within the 'object_name' parameter. Valid format: 'Page 1'[f8dvo24PdJ39fp6]"
|
|
1890
|
+
elif page_name is not None and visual_name is not None:
|
|
1891
|
+
page_name, page_display_name, visual_name, file_path = (
|
|
1892
|
+
helper.resolve_visual_name(
|
|
1893
|
+
self, page_name=page_name, visual_name=visual_name
|
|
1746
1894
|
)
|
|
1747
|
-
valid_page_name, valid_display_name, visual_name, file_path = (
|
|
1748
|
-
helper.resolve_visual_name(self, page_name=p_name, visual_name=v_name)
|
|
1749
1895
|
)
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1896
|
+
else:
|
|
1897
|
+
raise ValueError(
|
|
1898
|
+
f"{icons.red_dot} Invalid parameters. If specifying a visual_name you must specify the page_name."
|
|
1899
|
+
)
|
|
1754
1900
|
|
|
1755
|
-
|
|
1901
|
+
payload = self.rdef[self.rdef["path"] == file_path]["payload"].iloc[0]
|
|
1902
|
+
file = _decode_b64(payload)
|
|
1903
|
+
json_file = json.loads(file)
|
|
1756
1904
|
|
|
1757
|
-
|
|
1905
|
+
new_file = self.__set_annotation(
|
|
1906
|
+
json_file, name=annotation_name, value=annotation_value
|
|
1907
|
+
)
|
|
1908
|
+
new_payload = _conv_b64(new_file)
|
|
1758
1909
|
|
|
1759
|
-
|
|
1910
|
+
self._update_single_file(file_name=file_path, new_payload=new_payload)
|
|
1760
1911
|
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
if object_type not in object_types:
|
|
1764
|
-
raise ValueError(
|
|
1765
|
-
f"{icons.red_dot} Invalid object type. Valid options: {object_types}."
|
|
1766
|
-
)
|
|
1912
|
+
# Remove Annotations
|
|
1913
|
+
def __remove_annotation(self, json_file: dict, name: str) -> dict:
|
|
1767
1914
|
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1915
|
+
if "annotations" in json_file:
|
|
1916
|
+
json_file["annotations"] = [
|
|
1917
|
+
annotation
|
|
1918
|
+
for annotation in json_file["annotations"]
|
|
1919
|
+
if annotation["name"] != name
|
|
1920
|
+
]
|
|
1771
1921
|
|
|
1772
|
-
|
|
1773
|
-
object_type = object_type.capitalize()
|
|
1774
|
-
if object_type not in object_types:
|
|
1775
|
-
raise ValueError(
|
|
1776
|
-
f"{icons.red_dot} Invalid object type. Valid options: {object_types}."
|
|
1777
|
-
)
|
|
1922
|
+
return json_file
|
|
1778
1923
|
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
for ann in objJson["annotations"]:
|
|
1791
|
-
names.append(ann["name"])
|
|
1792
|
-
if name not in names:
|
|
1793
|
-
objJson["annotations"].append(new_annotation)
|
|
1794
|
-
else:
|
|
1795
|
-
for ann in objJson["annotations"]:
|
|
1796
|
-
if ann["name"] == name:
|
|
1797
|
-
ann["value"] = value
|
|
1798
|
-
return objJson
|
|
1924
|
+
def _remove_annotation(
|
|
1925
|
+
self,
|
|
1926
|
+
annotation_name: str,
|
|
1927
|
+
page_name: Optional[str] = None,
|
|
1928
|
+
visual_name: Optional[str] = None,
|
|
1929
|
+
):
|
|
1930
|
+
"""
|
|
1931
|
+
Removes an annotation on the report/page/visual.
|
|
1932
|
+
In order to remove a report annotation, leave page_name=None, visual_name=None.
|
|
1933
|
+
In order to remove a page annotation, leave visual_annotation=None.
|
|
1934
|
+
In order to remove a visual annotation, set all parameters.
|
|
1799
1935
|
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1936
|
+
Parameters
|
|
1937
|
+
----------
|
|
1938
|
+
annotation_name : str
|
|
1939
|
+
Name of the annotation.
|
|
1940
|
+
page_name : str, default=None
|
|
1941
|
+
The page name or page display name.
|
|
1942
|
+
Set this annotation when setting an annotation on a page or visual.
|
|
1943
|
+
visual_name : str, default=None
|
|
1944
|
+
The visual name.
|
|
1945
|
+
Set this property when setting an annotation on a visual.
|
|
1946
|
+
"""
|
|
1947
|
+
|
|
1948
|
+
if page_name is None and visual_name is None:
|
|
1949
|
+
file_path = "definition/report.json"
|
|
1950
|
+
elif page_name is not None and visual_name is None:
|
|
1810
1951
|
page_id, page_display, file_path = helper.resolve_page_name(
|
|
1811
1952
|
self, page_name=page_name
|
|
1812
1953
|
)
|
|
1954
|
+
elif page_name is not None and visual_name is not None:
|
|
1955
|
+
page_name, page_display_name, visual_name, file_path = (
|
|
1956
|
+
helper.resolve_visual_name(
|
|
1957
|
+
self, page_name=page_name, visual_name=visual_name
|
|
1958
|
+
)
|
|
1959
|
+
)
|
|
1960
|
+
else:
|
|
1961
|
+
raise ValueError(
|
|
1962
|
+
f"{icons.red_dot} Invalid parameters. If specifying a visual_name you must specify the page_name."
|
|
1963
|
+
)
|
|
1813
1964
|
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
payload = r["payload"]
|
|
1818
|
-
if object_type == "Report" and path == "definition/report.json":
|
|
1819
|
-
a = update_annotation(payload=payload)
|
|
1820
|
-
_add_part(request_body, path, _conv_b64(a))
|
|
1821
|
-
elif (
|
|
1822
|
-
object_type == "Page"
|
|
1823
|
-
and path == f"definition/pages/{page_id}/page.json"
|
|
1824
|
-
):
|
|
1825
|
-
a = update_annotation(payload=payload)
|
|
1826
|
-
_add_part(request_body, path, _conv_b64(a))
|
|
1827
|
-
elif (
|
|
1828
|
-
object_type == "Visual"
|
|
1829
|
-
and path
|
|
1830
|
-
== f"definition/pages/{page_id}/visuals/{visual_id}/visual.json"
|
|
1831
|
-
):
|
|
1832
|
-
a = update_annotation(payload=payload)
|
|
1833
|
-
_add_part(request_body, path, _conv_b64(a))
|
|
1834
|
-
else:
|
|
1835
|
-
_add_part(request_body, path, payload)
|
|
1965
|
+
payload = self.rdef[self.rdef["path"] == file_path]["payload"].iloc[0]
|
|
1966
|
+
file = _decode_b64(payload)
|
|
1967
|
+
json_file = json.loads(file)
|
|
1836
1968
|
|
|
1837
|
-
self.
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1969
|
+
new_file = self.__remove_annotation(json_file, name=annotation_name)
|
|
1970
|
+
new_payload = _conv_b64(new_file)
|
|
1971
|
+
|
|
1972
|
+
self._update_single_file(file_name=file_path, new_payload=new_payload)
|
|
1973
|
+
|
|
1974
|
+
# Get Annotation Value
|
|
1975
|
+
def __get_annotation_value(self, json_file: dict, name: str) -> str:
|
|
1976
|
+
|
|
1977
|
+
if "annotations" in json_file:
|
|
1978
|
+
for ann in json_file["annotations"]:
|
|
1979
|
+
if ann.get("name") == name:
|
|
1980
|
+
return ann.get("value")
|
|
1981
|
+
|
|
1982
|
+
def _get_annotation_value(
|
|
1983
|
+
self,
|
|
1984
|
+
annotation_name: str,
|
|
1985
|
+
page_name: Optional[str] = None,
|
|
1986
|
+
visual_name: Optional[str] = None,
|
|
1987
|
+
) -> str:
|
|
1988
|
+
"""
|
|
1989
|
+
Retrieves the annotation value of an annotation on the report/page/visual.
|
|
1990
|
+
In order to retrieve a report annotation value, leave page_name=None, visual_name=None.
|
|
1991
|
+
In order to retrieve a page annotation value, leave visual_annotation=None.
|
|
1992
|
+
In order to retrieve a visual annotation value, set all parameters.
|
|
1993
|
+
|
|
1994
|
+
Parameters
|
|
1995
|
+
----------
|
|
1996
|
+
annotation_name : str
|
|
1997
|
+
Name of the annotation.
|
|
1998
|
+
page_name : str, default=None
|
|
1999
|
+
The page name or page display name.
|
|
2000
|
+
Set this annotation when setting an annotation on a page or visual.
|
|
2001
|
+
visual_name : str, default=None
|
|
2002
|
+
The visual name.
|
|
2003
|
+
Set this property when setting an annotation on a visual.
|
|
2004
|
+
|
|
2005
|
+
Returns
|
|
2006
|
+
-------
|
|
2007
|
+
str
|
|
2008
|
+
The annotation value.
|
|
2009
|
+
"""
|
|
2010
|
+
|
|
2011
|
+
if page_name is None and visual_name is None:
|
|
2012
|
+
file_path = "definition/report.json"
|
|
2013
|
+
elif page_name is not None and visual_name is None:
|
|
2014
|
+
page_id, page_display, file_path = helper.resolve_page_name(
|
|
2015
|
+
self, page_name=page_name
|
|
1841
2016
|
)
|
|
1842
|
-
elif
|
|
1843
|
-
|
|
1844
|
-
|
|
2017
|
+
elif page_name is not None and visual_name is not None:
|
|
2018
|
+
page_name, page_display_name, visual_name, file_path = (
|
|
2019
|
+
helper.resolve_visual_name(
|
|
2020
|
+
self, page_name=page_name, visual_name=visual_name
|
|
2021
|
+
)
|
|
1845
2022
|
)
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
f"{icons.
|
|
2023
|
+
else:
|
|
2024
|
+
raise ValueError(
|
|
2025
|
+
f"{icons.red_dot} Invalid parameters. If specifying a visual_name you must specify the page_name."
|
|
1849
2026
|
)
|
|
1850
2027
|
|
|
2028
|
+
payload = self.rdef[self.rdef["path"] == file_path]["payload"].iloc[0]
|
|
2029
|
+
file = _decode_b64(payload)
|
|
2030
|
+
json_file = json.loads(file)
|
|
2031
|
+
|
|
2032
|
+
return self.__get_annotation_value(json_file, name=annotation_name)
|
|
2033
|
+
|
|
1851
2034
|
def __adjust_settings(
|
|
1852
2035
|
self, setting_type: str, setting_name: str, setting_value: bool
|
|
1853
2036
|
): # Meta function
|