semantic-link-labs 0.12.4__py3-none-any.whl → 0.12.5__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.12.4.dist-info → semantic_link_labs-0.12.5.dist-info}/METADATA +4 -3
- {semantic_link_labs-0.12.4.dist-info → semantic_link_labs-0.12.5.dist-info}/RECORD +23 -21
- sempy_labs/__init__.py +10 -8
- sempy_labs/_a_lib_info.py +1 -1
- sempy_labs/_dataflows.py +98 -10
- sempy_labs/_helper_functions.py +5 -1
- sempy_labs/_managed_private_endpoints.py +62 -0
- sempy_labs/_model_bpa.py +6 -0
- sempy_labs/_onelake.py +131 -0
- sempy_labs/admin/_basic_functions.py +17 -13
- sempy_labs/admin/_workspaces.py +2 -2
- sempy_labs/deployment_pipeline/__init__.py +21 -0
- sempy_labs/deployment_pipeline/_items.py +486 -0
- sempy_labs/directlake/_update_directlake_partition_entity.py +73 -41
- sempy_labs/graph/__init__.py +2 -0
- sempy_labs/graph/_groups.py +63 -0
- sempy_labs/graph/_users.py +61 -17
- sempy_labs/report/_export_report.py +0 -22
- sempy_labs/report/_report_rebind.py +29 -43
- sempy_labs/report/_reportwrapper.py +65 -30
- sempy_labs/_deployment_pipelines.py +0 -209
- {semantic_link_labs-0.12.4.dist-info → semantic_link_labs-0.12.5.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.12.4.dist-info → semantic_link_labs-0.12.5.dist-info}/licenses/LICENSE +0 -0
- {semantic_link_labs-0.12.4.dist-info → semantic_link_labs-0.12.5.dist-info}/top_level.txt +0 -0
sempy_labs/graph/_groups.py
CHANGED
|
@@ -236,6 +236,69 @@ def list_group_members(group: str | UUID) -> pd.DataFrame:
|
|
|
236
236
|
return df
|
|
237
237
|
|
|
238
238
|
|
|
239
|
+
@log
|
|
240
|
+
def list_group_transitive_members(group: str | UUID) -> pd.DataFrame:
|
|
241
|
+
"""
|
|
242
|
+
Shows a list of the members of a group. This operation is transitive and returns a flat list of all nested members.
|
|
243
|
+
|
|
244
|
+
This is a wrapper function for the following API: `List group transitive members <https://learn.microsoft.com/graph/api/group-list-transitivemembers>`_.
|
|
245
|
+
|
|
246
|
+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
247
|
+
|
|
248
|
+
Parameters
|
|
249
|
+
----------
|
|
250
|
+
group : str | uuid.UUID
|
|
251
|
+
The group name or ID.
|
|
252
|
+
|
|
253
|
+
Returns
|
|
254
|
+
-------
|
|
255
|
+
pandas.DataFrame
|
|
256
|
+
A pandas dataframe showing a list of the members of a group.
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
group_id = resolve_group_id(group)
|
|
260
|
+
|
|
261
|
+
result = _base_api(
|
|
262
|
+
request=f"groups/{group_id}/transitiveMembers",
|
|
263
|
+
client="graph",
|
|
264
|
+
uses_pagination=True,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
columns = {
|
|
268
|
+
"Member Id": "string",
|
|
269
|
+
"Organization Id": "string",
|
|
270
|
+
"Description": "string",
|
|
271
|
+
"Member Name": "string",
|
|
272
|
+
"Group Types": "list",
|
|
273
|
+
"Mail": "string",
|
|
274
|
+
"Mail Enabled": "bool",
|
|
275
|
+
"Mail Nickname": "string",
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
df = _create_dataframe(columns=columns)
|
|
279
|
+
|
|
280
|
+
rows = []
|
|
281
|
+
for r in result:
|
|
282
|
+
for v in r.get("value", []):
|
|
283
|
+
rows.append(
|
|
284
|
+
{
|
|
285
|
+
"Member Id": v.get("id"),
|
|
286
|
+
"Organization Id": v.get("organizationId"),
|
|
287
|
+
"Description": v.get("description"),
|
|
288
|
+
"Member Name": v.get("displayName"),
|
|
289
|
+
"Group Types": v.get("groupTypes"),
|
|
290
|
+
"Mail": v.get("mail"),
|
|
291
|
+
"Mail Enabled": v.get("mailEnabled"),
|
|
292
|
+
"Mail Nickname": v.get("mailNickname"),
|
|
293
|
+
}
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
if rows:
|
|
297
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
298
|
+
|
|
299
|
+
return df
|
|
300
|
+
|
|
301
|
+
|
|
239
302
|
@log
|
|
240
303
|
def list_group_owners(group: str | UUID) -> pd.DataFrame:
|
|
241
304
|
"""
|
sempy_labs/graph/_users.py
CHANGED
|
@@ -40,7 +40,7 @@ def resolve_user_id(user: str | UUID) -> UUID:
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
@log
|
|
43
|
-
def get_user(user: str | UUID) -> pd.DataFrame:
|
|
43
|
+
def get_user(user: str | UUID, show_manager: bool = False) -> pd.DataFrame:
|
|
44
44
|
"""
|
|
45
45
|
Shows properties of a given user.
|
|
46
46
|
|
|
@@ -52,6 +52,8 @@ def get_user(user: str | UUID) -> pd.DataFrame:
|
|
|
52
52
|
----------
|
|
53
53
|
user : str | uuid.UUID
|
|
54
54
|
The user ID or user principal name.
|
|
55
|
+
show_manager : bool, default=False
|
|
56
|
+
Whether to include the user's manager information.
|
|
55
57
|
|
|
56
58
|
Returns
|
|
57
59
|
-------
|
|
@@ -59,7 +61,11 @@ def get_user(user: str | UUID) -> pd.DataFrame:
|
|
|
59
61
|
A pandas dataframe showing properties of a given user.
|
|
60
62
|
"""
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
url = f"users/{user}?$select=id,userPrincipalName,displayName,mail,jobTitle,officeLocation,mobilePhone,businessPhones,preferredLanguage,surname,department"
|
|
65
|
+
if show_manager:
|
|
66
|
+
url += "&$expand=manager($select=displayName,id,mail,jobTitle)"
|
|
67
|
+
|
|
68
|
+
result = _base_api(request=url, client="graph").json()
|
|
63
69
|
|
|
64
70
|
new_data = {
|
|
65
71
|
"User Id": result.get("id"),
|
|
@@ -72,13 +78,22 @@ def get_user(user: str | UUID) -> pd.DataFrame:
|
|
|
72
78
|
"Business Phones": str(result.get("businessPhones")),
|
|
73
79
|
"Preferred Language": result.get("preferredLanguage"),
|
|
74
80
|
"Surname": result.get("surname"),
|
|
81
|
+
"Department": result.get("department"),
|
|
75
82
|
}
|
|
83
|
+
if show_manager:
|
|
84
|
+
manager = result.get("manager", {})
|
|
85
|
+
new_data |= {
|
|
86
|
+
"Manager Id": manager.get("id"),
|
|
87
|
+
"Manager Name": manager.get("displayName"),
|
|
88
|
+
"Manager Mail": manager.get("mail"),
|
|
89
|
+
"Manager Job Title": manager.get("jobTitle"),
|
|
90
|
+
}
|
|
76
91
|
|
|
77
92
|
return pd.DataFrame([new_data])
|
|
78
93
|
|
|
79
94
|
|
|
80
95
|
@log
|
|
81
|
-
def list_users() -> pd.DataFrame:
|
|
96
|
+
def list_users(show_manager: bool = False) -> pd.DataFrame:
|
|
82
97
|
"""
|
|
83
98
|
Shows a list of users and their properties.
|
|
84
99
|
|
|
@@ -86,13 +101,21 @@ def list_users() -> pd.DataFrame:
|
|
|
86
101
|
|
|
87
102
|
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
88
103
|
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
show_manager : bool, default=False
|
|
107
|
+
Whether to include the user's manager information.
|
|
108
|
+
|
|
89
109
|
Returns
|
|
90
110
|
-------
|
|
91
111
|
pandas.DataFrame
|
|
92
112
|
A pandas dataframe showing a list of users and their properties.
|
|
93
113
|
"""
|
|
94
114
|
|
|
95
|
-
|
|
115
|
+
url = "users?$select=id,userPrincipalName,displayName,mail,jobTitle,officeLocation,mobilePhone,businessPhones,preferredLanguage,surname,department"
|
|
116
|
+
if show_manager:
|
|
117
|
+
url += "&$expand=manager($select=displayName,id,mail,jobTitle)"
|
|
118
|
+
result = _base_api(request=url, client="graph", uses_pagination=True)
|
|
96
119
|
|
|
97
120
|
columns = {
|
|
98
121
|
"User Id": "string",
|
|
@@ -105,27 +128,48 @@ def list_users() -> pd.DataFrame:
|
|
|
105
128
|
"Business Phones": "string",
|
|
106
129
|
"Preferred Language": "string",
|
|
107
130
|
"Surname": "string",
|
|
131
|
+
"Department": "string",
|
|
108
132
|
}
|
|
109
133
|
|
|
134
|
+
if show_manager:
|
|
135
|
+
columns.update(
|
|
136
|
+
{
|
|
137
|
+
"Manager Id": "string",
|
|
138
|
+
"Manager Name": "string",
|
|
139
|
+
"Manager Mail": "string",
|
|
140
|
+
"Manager Job Title": "string",
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
|
|
110
144
|
df = _create_dataframe(columns=columns)
|
|
111
145
|
|
|
112
146
|
rows = []
|
|
113
147
|
for r in result:
|
|
114
148
|
for v in r.get("value", []):
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
user_data = {
|
|
150
|
+
"User Id": v.get("id"),
|
|
151
|
+
"User Principal Name": v.get("userPrincipalName"),
|
|
152
|
+
"User Name": v.get("displayName"),
|
|
153
|
+
"Mail": v.get("mail"),
|
|
154
|
+
"Job Title": v.get("jobTitle"),
|
|
155
|
+
"Office Location": v.get("officeLocation"),
|
|
156
|
+
"Mobile Phone": v.get("mobilePhone"),
|
|
157
|
+
"Business Phones": str(v.get("businessPhones")),
|
|
158
|
+
"Preferred Language": v.get("preferredLanguage"),
|
|
159
|
+
"Surname": v.get("surname"),
|
|
160
|
+
"Department": v.get("department"),
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if show_manager:
|
|
164
|
+
manager = v.get("manager", {})
|
|
165
|
+
user_data |= {
|
|
166
|
+
"Manager Id": manager.get("id"),
|
|
167
|
+
"Manager Name": manager.get("displayName"),
|
|
168
|
+
"Manager Mail": manager.get("mail"),
|
|
169
|
+
"Manager Job Title": manager.get("jobTitle"),
|
|
127
170
|
}
|
|
128
|
-
|
|
171
|
+
|
|
172
|
+
rows.append(user_data)
|
|
129
173
|
|
|
130
174
|
if rows:
|
|
131
175
|
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
@@ -12,10 +12,6 @@ from typing import Optional
|
|
|
12
12
|
from sempy._utils._log import log
|
|
13
13
|
import sempy_labs._icons as icons
|
|
14
14
|
from uuid import UUID
|
|
15
|
-
from sempy_labs.report._report_functions import (
|
|
16
|
-
list_report_visuals,
|
|
17
|
-
list_report_pages,
|
|
18
|
-
)
|
|
19
15
|
|
|
20
16
|
|
|
21
17
|
@log
|
|
@@ -187,15 +183,7 @@ def export_report(
|
|
|
187
183
|
request_body = {"format": export_format, "powerBIReportConfiguration": {}}
|
|
188
184
|
|
|
189
185
|
request_body["powerBIReportConfiguration"]["pages"] = []
|
|
190
|
-
dfPage = list_report_pages(report=report, workspace=workspace_id)
|
|
191
|
-
|
|
192
186
|
for page in page_name:
|
|
193
|
-
dfPage_filt = dfPage[dfPage["Page ID"] == page]
|
|
194
|
-
if len(dfPage_filt) == 0:
|
|
195
|
-
raise ValueError(
|
|
196
|
-
f"{icons.red_dot} The '{page}' page does not exist in the '{report}' report within the '{workspace_name}' workspace."
|
|
197
|
-
)
|
|
198
|
-
|
|
199
187
|
page_dict = {"pageName": page}
|
|
200
188
|
request_body["powerBIReportConfiguration"]["pages"].append(page_dict)
|
|
201
189
|
|
|
@@ -209,19 +197,9 @@ def export_report(
|
|
|
209
197
|
request_body = {"format": export_format, "powerBIReportConfiguration": {}}
|
|
210
198
|
|
|
211
199
|
request_body["powerBIReportConfiguration"]["pages"] = []
|
|
212
|
-
dfVisual = list_report_visuals(report=report, workspace=workspace_id)
|
|
213
200
|
a = 0
|
|
214
201
|
for page in page_name:
|
|
215
202
|
visual = visual_name[a]
|
|
216
|
-
|
|
217
|
-
dfVisual_filt = dfVisual[
|
|
218
|
-
(dfVisual["Page ID"] == page) & (dfVisual["Visual ID"] == visual)
|
|
219
|
-
]
|
|
220
|
-
if len(dfVisual_filt) == 0:
|
|
221
|
-
raise ValueError(
|
|
222
|
-
f"{icons.red_dot} The '{visual}' visual does not exist on the '{page}' in the '{report}' report within the '{workspace_name}' workspace."
|
|
223
|
-
)
|
|
224
|
-
|
|
225
203
|
page_dict = {"pageName": page, "visualName": visual}
|
|
226
204
|
request_body["powerBIReportConfiguration"]["pages"].append(page_dict)
|
|
227
205
|
a += 1
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
from sempy_labs._helper_functions import (
|
|
2
|
+
resolve_item_id,
|
|
3
|
+
resolve_workspace_id,
|
|
2
4
|
resolve_workspace_name_and_id,
|
|
3
5
|
resolve_item_name_and_id,
|
|
4
6
|
_base_api,
|
|
@@ -8,6 +10,7 @@ from typing import Optional, List
|
|
|
8
10
|
from sempy._utils._log import log
|
|
9
11
|
import sempy_labs._icons as icons
|
|
10
12
|
from uuid import UUID
|
|
13
|
+
import sempy.fabric as fabric
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
@log
|
|
@@ -108,57 +111,40 @@ def report_rebind_all(
|
|
|
108
111
|
the new semantic model.
|
|
109
112
|
"""
|
|
110
113
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
(dataset_name, dataset_id) = resolve_dataset_name_and_id(
|
|
114
|
-
dataset=dataset, workspace=dataset_workspace
|
|
114
|
+
(dataset_name, dataset_id) = resolve_item_name_and_id(
|
|
115
|
+
item=dataset, type="SemanticModel", workspace=dataset_workspace
|
|
115
116
|
)
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
new_dataset_id = resolve_item_id(
|
|
118
|
+
item=new_dataset, type="SemanticModel", workspace=new_dataset_workspace
|
|
118
119
|
)
|
|
119
120
|
|
|
120
121
|
if dataset_id == new_dataset_id:
|
|
121
122
|
raise ValueError(
|
|
122
|
-
f"{icons.red_dot} The 'dataset' and 'new_dataset' parameters are both set to
|
|
123
|
+
f"{icons.red_dot} The 'dataset' and 'new_dataset' parameters are both set to the same semantic model within the same workspace. These parameters must be set to different values."
|
|
123
124
|
)
|
|
124
|
-
|
|
125
|
-
workspace=dataset_workspace
|
|
126
|
-
)
|
|
125
|
+
dataset_workspace_id = resolve_workspace_id(workspace=dataset_workspace)
|
|
127
126
|
|
|
128
|
-
if isinstance(report_workspace, str):
|
|
127
|
+
if isinstance(report_workspace, str) or report_workspace is None:
|
|
129
128
|
report_workspace = [report_workspace]
|
|
130
129
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
if dfR.empty:
|
|
136
|
-
print(
|
|
137
|
-
f"{icons.info} The '{dataset_name}' semantic model within the '{dataset_workspace_name}' workspace has no dependent reports."
|
|
138
|
-
)
|
|
139
|
-
return
|
|
140
|
-
|
|
141
|
-
if report_workspace is None:
|
|
142
|
-
dfR_filt = dfR.copy()
|
|
143
|
-
else:
|
|
130
|
+
for w in report_workspace:
|
|
131
|
+
dfR = fabric.list_reports(workspace=w)
|
|
144
132
|
dfR_filt = dfR[
|
|
145
|
-
(dfR["
|
|
146
|
-
|
|
133
|
+
(dfR["Dataset ID"] == dataset_id)
|
|
134
|
+
& (dfR["Dataset Workspace Id"] == dataset_workspace_id)
|
|
147
135
|
]
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
dataset_workspace=new_dataset_workspace,
|
|
164
|
-
)
|
|
136
|
+
if dfR_filt.empty:
|
|
137
|
+
(wksp_name, _) = resolve_workspace_name_and_id(workspace=w)
|
|
138
|
+
print(
|
|
139
|
+
f"{icons.info} No reports found for the '{dataset_name}' semantic model within the '{wksp_name}' workspace."
|
|
140
|
+
)
|
|
141
|
+
else:
|
|
142
|
+
# Rebind reports to new dataset
|
|
143
|
+
for _, r in dfR_filt.iterrows():
|
|
144
|
+
rpt_name = r["Name"]
|
|
145
|
+
report_rebind(
|
|
146
|
+
report=rpt_name,
|
|
147
|
+
dataset=new_dataset,
|
|
148
|
+
report_workspace=w,
|
|
149
|
+
dataset_workspace=new_dataset_workspace,
|
|
150
|
+
)
|
|
@@ -171,6 +171,7 @@ class ReportWrapper:
|
|
|
171
171
|
self,
|
|
172
172
|
file_path: str,
|
|
173
173
|
json_path: Optional[str] = None,
|
|
174
|
+
verbose: bool = True,
|
|
174
175
|
) -> dict | List[Tuple[str, dict]]:
|
|
175
176
|
"""
|
|
176
177
|
Get the json content of the specified report definition file.
|
|
@@ -181,6 +182,8 @@ class ReportWrapper:
|
|
|
181
182
|
The path of the report definition file. For example: "definition/pages/pages.json". You may also use wildcards. For example: "definition/pages/*/page.json".
|
|
182
183
|
json_path : str, default=None
|
|
183
184
|
The json path to the specific part of the file to be retrieved. If None, the entire file content is returned.
|
|
185
|
+
verbose : bool, default=True
|
|
186
|
+
If True, prints messages about the retrieval process. If False, suppresses these messages.
|
|
184
187
|
|
|
185
188
|
Returns
|
|
186
189
|
-------
|
|
@@ -192,6 +195,7 @@ class ReportWrapper:
|
|
|
192
195
|
|
|
193
196
|
# Find matching parts
|
|
194
197
|
if "*" in file_path:
|
|
198
|
+
results = []
|
|
195
199
|
matching_parts = [
|
|
196
200
|
(part.get("path"), part.get("payload"))
|
|
197
201
|
for part in parts
|
|
@@ -199,9 +203,11 @@ class ReportWrapper:
|
|
|
199
203
|
]
|
|
200
204
|
|
|
201
205
|
if not matching_parts:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
206
|
+
if verbose:
|
|
207
|
+
print(
|
|
208
|
+
f"{icons.red_dot} No files match the wildcard path '{file_path}'."
|
|
209
|
+
)
|
|
210
|
+
return results
|
|
205
211
|
|
|
206
212
|
results = []
|
|
207
213
|
for path, payload in matching_parts:
|
|
@@ -220,8 +226,8 @@ class ReportWrapper:
|
|
|
220
226
|
# raise ValueError(
|
|
221
227
|
# f"{icons.red_dot} No match found for '{json_path}' in '{path}'."
|
|
222
228
|
# )
|
|
223
|
-
if not results:
|
|
224
|
-
|
|
229
|
+
if not results and verbose:
|
|
230
|
+
print(
|
|
225
231
|
f"{icons.red_dot} No match found for '{json_path}' in any of the files matching the wildcard path '{file_path}'."
|
|
226
232
|
)
|
|
227
233
|
return results
|
|
@@ -241,14 +247,11 @@ class ReportWrapper:
|
|
|
241
247
|
matches = jsonpath_expr.find(payload)
|
|
242
248
|
if matches:
|
|
243
249
|
return matches[0].value
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
f"{icons.red_dot} No match found for '{json_path}'."
|
|
247
|
-
)
|
|
250
|
+
elif verbose:
|
|
251
|
+
print(f"{icons.red_dot} No match found for '{json_path}'.")
|
|
248
252
|
|
|
249
|
-
|
|
250
|
-
f"{icons.red_dot} File '{file_path}' not found in report definition."
|
|
251
|
-
)
|
|
253
|
+
if verbose:
|
|
254
|
+
print(f"{icons.red_dot} File '{file_path}' not found in report definition.")
|
|
252
255
|
|
|
253
256
|
def add(self, file_path: str, payload: dict | bytes):
|
|
254
257
|
"""
|
|
@@ -674,33 +677,65 @@ class ReportWrapper:
|
|
|
674
677
|
columns = {
|
|
675
678
|
"Custom Visual Name": "str",
|
|
676
679
|
"Custom Visual Display Name": "str",
|
|
680
|
+
"Is Public": "bool",
|
|
677
681
|
"Used in Report": "bool",
|
|
678
682
|
}
|
|
679
683
|
|
|
680
684
|
df = _create_dataframe(columns=columns)
|
|
681
685
|
|
|
682
|
-
|
|
686
|
+
visuals = []
|
|
687
|
+
rp = self.get(
|
|
688
|
+
file_path=self._report_file_path,
|
|
689
|
+
json_path="$.resourcePackages",
|
|
690
|
+
verbose=False,
|
|
691
|
+
)
|
|
692
|
+
|
|
693
|
+
if rp:
|
|
694
|
+
visuals += [
|
|
695
|
+
{"Custom Visual Name": item.get("name"), "Is Public": False}
|
|
696
|
+
for item in rp
|
|
697
|
+
if item.get("type") == "CustomVisual"
|
|
698
|
+
]
|
|
683
699
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
700
|
+
# Load public custom visuals
|
|
701
|
+
public_custom_visuals = (
|
|
702
|
+
self.get(
|
|
703
|
+
file_path=self._report_file_path,
|
|
704
|
+
json_path="$.publicCustomVisuals",
|
|
705
|
+
verbose=False,
|
|
706
|
+
)
|
|
707
|
+
or []
|
|
687
708
|
)
|
|
688
709
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
if r["Custom Visual Name"] in visual_types:
|
|
699
|
-
df.at[_, "Used in Report"] = True
|
|
700
|
-
else:
|
|
701
|
-
df.at[_, "Used in Report"] = False
|
|
710
|
+
visuals += [
|
|
711
|
+
{
|
|
712
|
+
"Custom Visual Name": (
|
|
713
|
+
item.get("name") if isinstance(item, dict) else item
|
|
714
|
+
),
|
|
715
|
+
"Is Public": True,
|
|
716
|
+
}
|
|
717
|
+
for item in public_custom_visuals
|
|
718
|
+
]
|
|
702
719
|
|
|
703
|
-
|
|
720
|
+
if visuals:
|
|
721
|
+
df = pd.DataFrame(visuals, columns=list(columns.keys()))
|
|
722
|
+
|
|
723
|
+
# df["Custom Visual Name"] = report_file.get("publicCustomVisuals")
|
|
724
|
+
df["Custom Visual Display Name"] = df["Custom Visual Name"].apply(
|
|
725
|
+
lambda x: helper.vis_type_mapping.get(x, x)
|
|
726
|
+
)
|
|
727
|
+
|
|
728
|
+
visual_types = set()
|
|
729
|
+
for v in self.__all_visuals():
|
|
730
|
+
payload = v.get("payload", {})
|
|
731
|
+
visual = payload.get("visual", {})
|
|
732
|
+
visual_type = visual.get("visualType")
|
|
733
|
+
if visual_type:
|
|
734
|
+
visual_types.add(visual_type)
|
|
735
|
+
|
|
736
|
+
df["Used in Report"] = df["Custom Visual Name"].isin(visual_types)
|
|
737
|
+
|
|
738
|
+
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
704
739
|
|
|
705
740
|
return df
|
|
706
741
|
|