semantic-link-labs 0.5.0__py3-none-any.whl → 0.7.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.

Files changed (113) hide show
  1. semantic_link_labs-0.7.0.dist-info/METADATA +148 -0
  2. semantic_link_labs-0.7.0.dist-info/RECORD +111 -0
  3. {semantic_link_labs-0.5.0.dist-info → semantic_link_labs-0.7.0.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +45 -15
  5. sempy_labs/_ai.py +42 -85
  6. sempy_labs/_bpa_translation/_translations_am-ET.po +828 -0
  7. sempy_labs/_bpa_translation/_translations_ar-AE.po +860 -0
  8. sempy_labs/_bpa_translation/_translations_cs-CZ.po +894 -0
  9. sempy_labs/_bpa_translation/_translations_da-DK.po +894 -0
  10. sempy_labs/_bpa_translation/_translations_de-DE.po +933 -0
  11. sempy_labs/_bpa_translation/_translations_el-GR.po +936 -0
  12. sempy_labs/_bpa_translation/_translations_es-ES.po +915 -0
  13. sempy_labs/_bpa_translation/_translations_fa-IR.po +883 -0
  14. sempy_labs/_bpa_translation/_translations_fr-FR.po +938 -0
  15. sempy_labs/_bpa_translation/_translations_ga-IE.po +912 -0
  16. sempy_labs/_bpa_translation/_translations_he-IL.po +855 -0
  17. sempy_labs/_bpa_translation/_translations_hi-IN.po +892 -0
  18. sempy_labs/_bpa_translation/_translations_hu-HU.po +910 -0
  19. sempy_labs/_bpa_translation/_translations_is-IS.po +887 -0
  20. sempy_labs/_bpa_translation/_translations_it-IT.po +931 -0
  21. sempy_labs/_bpa_translation/_translations_ja-JP.po +805 -0
  22. sempy_labs/_bpa_translation/_translations_nl-NL.po +924 -0
  23. sempy_labs/_bpa_translation/_translations_pl-PL.po +913 -0
  24. sempy_labs/_bpa_translation/_translations_pt-BR.po +909 -0
  25. sempy_labs/_bpa_translation/_translations_pt-PT.po +904 -0
  26. sempy_labs/_bpa_translation/_translations_ru-RU.po +909 -0
  27. sempy_labs/_bpa_translation/_translations_ta-IN.po +922 -0
  28. sempy_labs/_bpa_translation/_translations_te-IN.po +896 -0
  29. sempy_labs/_bpa_translation/_translations_th-TH.po +873 -0
  30. sempy_labs/_bpa_translation/_translations_zh-CN.po +767 -0
  31. sempy_labs/_bpa_translation/_translations_zu-ZA.po +916 -0
  32. sempy_labs/_clear_cache.py +12 -8
  33. sempy_labs/_connections.py +77 -70
  34. sempy_labs/_dax.py +7 -9
  35. sempy_labs/_generate_semantic_model.py +75 -90
  36. sempy_labs/_helper_functions.py +371 -20
  37. sempy_labs/_icons.py +23 -0
  38. sempy_labs/_list_functions.py +855 -427
  39. sempy_labs/_model_auto_build.py +4 -3
  40. sempy_labs/_model_bpa.py +307 -1118
  41. sempy_labs/_model_bpa_bulk.py +363 -0
  42. sempy_labs/_model_bpa_rules.py +831 -0
  43. sempy_labs/_model_dependencies.py +20 -16
  44. sempy_labs/_one_lake_integration.py +18 -12
  45. sempy_labs/_query_scale_out.py +116 -129
  46. sempy_labs/_refresh_semantic_model.py +23 -10
  47. sempy_labs/_translations.py +367 -288
  48. sempy_labs/_vertipaq.py +152 -123
  49. sempy_labs/directlake/__init__.py +7 -1
  50. sempy_labs/directlake/_directlake_schema_compare.py +33 -30
  51. sempy_labs/directlake/_directlake_schema_sync.py +60 -77
  52. sempy_labs/directlake/_dl_helper.py +233 -0
  53. sempy_labs/directlake/_get_directlake_lakehouse.py +7 -8
  54. sempy_labs/directlake/_get_shared_expression.py +5 -3
  55. sempy_labs/directlake/_guardrails.py +20 -16
  56. sempy_labs/directlake/_list_directlake_model_calc_tables.py +17 -10
  57. sempy_labs/directlake/_show_unsupported_directlake_objects.py +3 -2
  58. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +10 -5
  59. sempy_labs/directlake/_update_directlake_partition_entity.py +169 -22
  60. sempy_labs/directlake/_warm_cache.py +7 -4
  61. sempy_labs/lakehouse/_get_lakehouse_columns.py +1 -1
  62. sempy_labs/lakehouse/_get_lakehouse_tables.py +65 -71
  63. sempy_labs/lakehouse/_lakehouse.py +5 -3
  64. sempy_labs/lakehouse/_shortcuts.py +20 -13
  65. sempy_labs/migration/__init__.py +1 -1
  66. sempy_labs/migration/_create_pqt_file.py +184 -186
  67. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +240 -269
  68. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +78 -77
  69. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +444 -425
  70. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +96 -102
  71. sempy_labs/migration/_migration_validation.py +2 -2
  72. sempy_labs/migration/_refresh_calc_tables.py +94 -100
  73. sempy_labs/report/_BPAReportTemplate.json +232 -0
  74. sempy_labs/report/__init__.py +6 -2
  75. sempy_labs/report/_bpareporttemplate/.pbi/localSettings.json +9 -0
  76. sempy_labs/report/_bpareporttemplate/.platform +11 -0
  77. sempy_labs/report/_bpareporttemplate/StaticResources/SharedResources/BaseThemes/CY24SU06.json +710 -0
  78. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/page.json +11 -0
  79. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/1b08bce3bebabb0a27a8/visual.json +191 -0
  80. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/2f22ddb70c301693c165/visual.json +438 -0
  81. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/3b1182230aa6c600b43a/visual.json +127 -0
  82. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/58577ba6380c69891500/visual.json +576 -0
  83. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/a2a8fa5028b3b776c96c/visual.json +207 -0
  84. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/adfd47ef30652707b987/visual.json +506 -0
  85. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/b6a80ee459e716e170b1/visual.json +127 -0
  86. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/ce3130a721c020cc3d81/visual.json +513 -0
  87. sempy_labs/report/_bpareporttemplate/definition/pages/92735ae19b31712208ad/page.json +8 -0
  88. sempy_labs/report/_bpareporttemplate/definition/pages/92735ae19b31712208ad/visuals/66e60dfb526437cd78d1/visual.json +112 -0
  89. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/page.json +11 -0
  90. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/07deb8bce824e1be37d7/visual.json +513 -0
  91. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0b1c68838818b32ad03b/visual.json +352 -0
  92. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0c171de9d2683d10b930/visual.json +37 -0
  93. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0efa01be0510e40a645e/visual.json +542 -0
  94. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/6bf2f0eb830ab53cc668/visual.json +221 -0
  95. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/88d8141cb8500b60030c/visual.json +127 -0
  96. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/a753273590beed656a03/visual.json +576 -0
  97. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/b8fdc82cddd61ac447bc/visual.json +127 -0
  98. sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/page.json +9 -0
  99. sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/visuals/ce8532a7e25020271077/visual.json +38 -0
  100. sempy_labs/report/_bpareporttemplate/definition/pages/pages.json +10 -0
  101. sempy_labs/report/_bpareporttemplate/definition/report.json +176 -0
  102. sempy_labs/report/_bpareporttemplate/definition/version.json +4 -0
  103. sempy_labs/report/_bpareporttemplate/definition.pbir +14 -0
  104. sempy_labs/report/_generate_report.py +260 -139
  105. sempy_labs/report/_report_functions.py +90 -59
  106. sempy_labs/report/_report_rebind.py +40 -34
  107. sempy_labs/tom/__init__.py +1 -4
  108. sempy_labs/tom/_model.py +601 -181
  109. semantic_link_labs-0.5.0.dist-info/METADATA +0 -22
  110. semantic_link_labs-0.5.0.dist-info/RECORD +0 -53
  111. sempy_labs/directlake/_fallback.py +0 -58
  112. {semantic_link_labs-0.5.0.dist-info → semantic_link_labs-0.7.0.dist-info}/LICENSE +0 -0
  113. {semantic_link_labs-0.5.0.dist-info → semantic_link_labs-0.7.0.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,18 @@
1
- import sempy
2
1
  import sempy.fabric as fabric
3
2
  import pandas as pd
4
- import json, base64, time
3
+ import json
4
+ import os
5
+ import time
5
6
  from typing import Optional
6
- from sempy_labs._helper_functions import resolve_workspace_name_and_id
7
+ from sempy_labs._helper_functions import (
8
+ resolve_workspace_name_and_id,
9
+ _conv_b64,
10
+ resolve_report_id,
11
+ lro,
12
+ )
7
13
  import sempy_labs._icons as icons
14
+ from sempy._utils._log import log
15
+ from sempy.fabric.exceptions import FabricHTTPException
8
16
 
9
17
 
10
18
  def create_report_from_reportjson(
@@ -35,18 +43,18 @@ def create_report_from_reportjson(
35
43
 
36
44
  (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
37
45
 
38
- objectType = "Report"
46
+ dfI = fabric.list_items(workspace=workspace)
39
47
 
40
- dfI_m = fabric.list_items(workspace=workspace, type="SemanticModel")
41
- dfI_model = dfI_m[(dfI_m["Display Name"] == dataset)]
48
+ dfI_model = dfI[(dfI["Display Name"] == dataset) & (dfI["Type"] == "SemanticModel")]
42
49
 
43
50
  if len(dfI_model) == 0:
44
- raise ValueError(f"{icons.red_dot} The '{dataset}' semantic model does not exist in the '{workspace}' workspace.")
51
+ raise ValueError(
52
+ f"{icons.red_dot} The '{dataset}' semantic model does not exist in the '{workspace}' workspace."
53
+ )
45
54
 
46
55
  datasetId = dfI_model["Id"].iloc[0]
47
56
 
48
- dfI_r = fabric.list_items(workspace=workspace, type="Report")
49
- dfI_rpt = dfI_r[(dfI_r["Display Name"] == report)]
57
+ dfI_rpt = dfI[(dfI["Display Name"] == report) & (dfI["Type"] == "Report")]
50
58
 
51
59
  if len(dfI_rpt) > 0:
52
60
  print(
@@ -70,83 +78,50 @@ def create_report_from_reportjson(
70
78
  },
71
79
  }
72
80
 
73
- def conv_b64(file):
74
-
75
- loadJson = json.dumps(file)
76
- f = base64.b64encode(loadJson.encode("utf-8")).decode("utf-8")
77
-
78
- return f
79
-
80
- definitionPBIR = conv_b64(defPBIR)
81
- payloadReportJson = conv_b64(report_json)
82
-
83
- if theme_json is None:
84
- request_body = {
85
- "displayName": report,
86
- "type": objectType,
87
- "definition": {
88
- "parts": [
89
- {
90
- "path": "report.json",
91
- "payload": payloadReportJson,
92
- "payloadType": "InlineBase64",
93
- },
94
- {
95
- "path": "definition.pbir",
96
- "payload": definitionPBIR,
97
- "payloadType": "InlineBase64",
98
- },
99
- ]
100
- },
101
- }
102
- else:
103
- payloadThemeJson = conv_b64(theme_json)
104
- themeID = theme_json["payload"]["blob"]["displayName"]
105
- themePath = "StaticResources/SharedResources/BaseThemes/" + themeID + ".json"
106
- request_body = {
107
- "displayName": report,
108
- "type": objectType,
109
- "definition": {
110
- "parts": [
111
- {
112
- "path": "report.json",
113
- "payload": payloadReportJson,
114
- "payloadType": "InlineBase64",
115
- },
116
- {
117
- "path": themePath,
118
- "payload": payloadThemeJson,
119
- "payloadType": "InlineBase64",
120
- },
121
- {
122
- "path": "definition.pbir",
123
- "payload": definitionPBIR,
124
- "payloadType": "InlineBase64",
125
- },
126
- ]
127
- },
81
+ definitionPBIR = _conv_b64(defPBIR)
82
+ payloadReportJson = _conv_b64(report_json)
83
+
84
+ request_body = {
85
+ "displayName": report,
86
+ "definition": {
87
+ "parts": [
88
+ {
89
+ "path": "report.json",
90
+ "payload": payloadReportJson,
91
+ "payloadType": "InlineBase64",
92
+ },
93
+ {
94
+ "path": "definition.pbir",
95
+ "payload": definitionPBIR,
96
+ "payloadType": "InlineBase64",
97
+ },
98
+ ]
99
+ },
100
+ }
101
+
102
+ if theme_json is not None:
103
+ theme_payload = _conv_b64(theme_json)
104
+ theme_id = theme_json["payload"]["blob"]["displayName"]
105
+ theme_path = f"StaticResources/SharedResources/BaseThemes/{theme_id}.json"
106
+
107
+ part = {
108
+ "path": theme_path,
109
+ "payload": theme_payload,
110
+ "payloadType": "InlineBase64",
128
111
  }
112
+ request_body["definition"]["parts"].append(part)
113
+
114
+ response = client.post(f"/v1/workspaces/{workspace_id}/reports", json=request_body)
129
115
 
130
- response = client.post(f"/v1/workspaces/{workspace_id}/items", json=request_body)
116
+ lro(client, response, status_codes=[201, 202])
131
117
 
132
- if response.status_code == 201:
133
- print(f"{icons.green_dot} Report creation succeeded")
134
- print(response.json())
135
- elif response.status_code == 202:
136
- operationId = response.headers["x-ms-operation-id"]
137
- response = client.get(f"/v1/operations/{operationId}")
138
- response_body = json.loads(response.content)
139
- while response_body["status"] != "Succeeded":
140
- time.sleep(3)
141
- response = client.get(f"/v1/operations/{operationId}")
142
- response_body = json.loads(response.content)
143
- response = client.get(f"/v1/operations/{operationId}/result")
144
- print(f"{icons.green_dot} Report creation succeeded")
145
- print(response.json())
118
+ print(
119
+ f"{icons.green_dot} Succesfully created the '{report}' report within the '{workspace}' workspace."
120
+ )
146
121
 
147
122
 
148
123
  def update_report_from_reportjson(
149
- report: str, report_json: str, workspace: Optional[str] = None
124
+ report: str, report_json: dict, workspace: Optional[str] = None
150
125
  ):
151
126
  """
152
127
  Updates a report based on a report.json file.
@@ -155,7 +130,7 @@ def update_report_from_reportjson(
155
130
  ----------
156
131
  report : str
157
132
  Name of the report.
158
- report_json : str
133
+ report_json : dict
159
134
  The report.json file to be used to update the report.
160
135
  workspace : str, default=None
161
136
  The Fabric workspace name in which the report resides.
@@ -164,53 +139,15 @@ def update_report_from_reportjson(
164
139
  """
165
140
 
166
141
  (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
142
+ report_id = resolve_report_id(report=report, workspace=workspace)
167
143
 
168
- dfR = fabric.list_reports(workspace=workspace)
169
- dfR_filt = dfR[(dfR["Name"] == report) & (dfR["Report Type"] == "PowerBIReport")]
170
-
171
- if len(dfR_filt) == 0:
172
- raise ValueError(f"{icons.red_dot} The '{report}' report does not exist in the '{workspace}' workspace.")
173
-
174
- reportId = dfR_filt["Id"].iloc[0]
175
- client = fabric.FabricRestClient()
176
-
177
- response = client.post(
178
- f"/v1/workspaces/{workspace_id}/items/{reportId}/getDefinition"
179
- )
180
- df_items = pd.json_normalize(response.json()["definition"]["parts"])
144
+ # Get the existing PBIR file
145
+ df_items = get_report_definition(report=report, workspace=workspace)
181
146
  df_items_filt = df_items[df_items["path"] == "definition.pbir"]
182
147
  rptDefFile = df_items_filt["payload"].iloc[0]
183
- # datasetId = dfR_filt['Dataset Id'].iloc[0]
184
- # datasetWorkspaceId = dfR_filt['Dataset Workspace Id'].iloc[0]
185
-
186
- # defPBIR = {
187
- # "version": "1.0",
188
- # "datasetReference": {
189
- # "byPath": None,
190
- # "byConnection": {
191
- # "connectionString": None,
192
- # "pbiServiceModelId": None,
193
- # "pbiModelVirtualServerName": "sobe_wowvirtualserver",
194
- # "pbiModelDatabaseName": datasetId,
195
- # "name": "EntityDataSource",
196
- # "connectionType": "pbiServiceXmlaStyleLive"
197
- # }
198
- # }
199
- # }
200
-
201
- def conv_b64(file):
202
-
203
- loadJson = json.dumps(file)
204
- f = base64.b64encode(loadJson.encode("utf-8")).decode("utf-8")
205
-
206
- return f
207
-
208
- # definitionPBIR = conv_b64(defPBIR)
209
- payloadReportJson = conv_b64(report_json)
148
+ payloadReportJson = _conv_b64(report_json)
210
149
 
211
150
  request_body = {
212
- "displayName": report,
213
- "type": 'Report',
214
151
  "definition": {
215
152
  "parts": [
216
153
  {
@@ -224,25 +161,209 @@ def update_report_from_reportjson(
224
161
  "payloadType": "InlineBase64",
225
162
  },
226
163
  ]
227
- },
164
+ }
228
165
  }
229
166
 
167
+ client = fabric.FabricRestClient()
230
168
  response = client.post(
231
- f"/v1/workspaces/{workspace_id}/reports/{reportId}/updateDefinition",
169
+ f"/v1/workspaces/{workspace_id}/reports/{report_id}/updateDefinition",
232
170
  json=request_body,
233
171
  )
234
172
 
235
- if response.status_code == 201:
236
- print(f"{icons.green_dot} The '{report}' report has been successfully updated.")
237
- # print(response.json())
238
- elif response.status_code == 202:
239
- operationId = response.headers["x-ms-operation-id"]
240
- response = client.get(f"/v1/operations/{operationId}")
241
- response_body = json.loads(response.content)
242
- while response_body["status"] != "Succeeded":
243
- time.sleep(3)
244
- response = client.get(f"/v1/operations/{operationId}")
245
- response_body = json.loads(response.content)
246
- response = client.get(f"/v1/operations/{operationId}/result")
247
- print(f"{icons.green_dot} The '{report}' report has been successfully updated.")
248
- # print(response.json())
173
+ lro(client, response, return_status_code=True)
174
+
175
+ print(
176
+ f"{icons.green_dot} The '{report}' report within the '{workspace}' workspace has been successfully updated."
177
+ )
178
+
179
+
180
+ def get_report_definition(report: str, workspace: Optional[str] = None) -> pd.DataFrame:
181
+ """
182
+ Gets the collection of definition files of a report.
183
+
184
+ Parameters
185
+ ----------
186
+ report : str
187
+ Name of the report.
188
+ workspace : str, default=None
189
+ The Fabric workspace name in which the report resides.
190
+ Defaults to None which resolves to the workspace of the attached lakehouse
191
+ or if no lakehouse attached, resolves to the workspace of the notebook.
192
+
193
+ Returns
194
+ -------
195
+ pandas.DataFrame
196
+ The collection of report definition files within a pandas dataframe.
197
+ """
198
+
199
+ (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
200
+
201
+ report_id = resolve_report_id(report=report, workspace=workspace)
202
+ client = fabric.FabricRestClient()
203
+ response = client.post(
204
+ f"/v1/workspaces/{workspace_id}/reports/{report_id}/getDefinition",
205
+ )
206
+
207
+ result = lro(client, response).json()
208
+ rdef = pd.json_normalize(result["definition"]["parts"])
209
+
210
+ return rdef
211
+
212
+
213
+ @log
214
+ def create_model_bpa_report(
215
+ report: Optional[str] = icons.model_bpa_name,
216
+ dataset: Optional[str] = icons.model_bpa_name,
217
+ dataset_workspace: Optional[str] = None,
218
+ ):
219
+ """
220
+ Dynamically generates a Best Practice Analyzer report for analyzing semantic models.
221
+
222
+ Parameters
223
+ ----------
224
+ report : str, default='ModelBPA'
225
+ Name of the report.
226
+ Defaults to 'ModelBPA'.
227
+ dataset : str, default='ModelBPA'
228
+ Name of the semantic model which feeds this report.
229
+ Defaults to 'ModelBPA'
230
+ dataset_workspace : str, default=None
231
+ The Fabric workspace name in which the semantic model resides.
232
+ Defaults to None which resolves to the workspace of the attached lakehouse
233
+ or if no lakehouse attached, resolves to the workspace of the notebook.
234
+
235
+ """
236
+
237
+ # from sempy_labs._helper_functions import resolve_dataset_id
238
+
239
+ dfI = fabric.list_items(workspace=dataset_workspace, type="SemanticModel")
240
+ dfI_filt = dfI[dfI["Display Name"] == dataset]
241
+
242
+ if len(dfI_filt) == 0:
243
+ raise ValueError(
244
+ f"The '{dataset}' semantic model does not exist within the '{dataset_workspace}' workspace."
245
+ )
246
+
247
+ dfR = fabric.list_reports(workspace=dataset_workspace)
248
+ dfR_filt = dfR[dfR["Name"] == report]
249
+ # dataset_id = resolve_dataset_id(dataset=dataset, workspace=dataset_workspace)
250
+
251
+ current_dir = os.path.dirname(__file__)
252
+ # directory_path = os.path.join(current_dir, "_bpareporttemplate")
253
+ # len_dir_path = len(directory_path) + 1
254
+
255
+ # request_body = {"displayName": report, "definition": {"parts": []}}
256
+
257
+ # def get_all_file_paths(directory):
258
+ # file_paths = []
259
+
260
+ # for root, directories, files in os.walk(directory):
261
+ # for filename in files:
262
+ # full_path = os.path.join(root, filename)
263
+ # file_paths.append(full_path)
264
+
265
+ # return file_paths
266
+
267
+ # all_files = get_all_file_paths(directory_path)
268
+
269
+ # for file_path in all_files:
270
+ # fp = file_path[len_dir_path:]
271
+ # with open(file_path, "r") as file:
272
+ # json_file = json.load(file)
273
+ # if fp == 'definition.pbir':
274
+ # conn_string = f"Data Source=powerbi://api.powerbi.com/v1.0/myorg/{dataset_workspace};Initial Catalog={dataset};Integrated Security=ClaimsToken"
275
+ # json_file['datasetReference']['byConnection']['connectionString'] = conn_string
276
+ # json_file['datasetReference']['byConnection']['pbiModelDatabaseName'] = dataset_id
277
+ # part = {
278
+ # "path": fp,
279
+ # "payload": _conv_b64(json_file),
280
+ # "payloadType": "InlineBase64",
281
+ # }
282
+
283
+ # request_body["definition"]["parts"].append(part)
284
+
285
+ # _create_report(
286
+ # report=report,
287
+ # request_body=request_body,
288
+ # dataset=dataset,
289
+ # report_workspace=dataset_workspace,
290
+ # dataset_workspace=dataset_workspace,
291
+ # )
292
+
293
+ json_file_path = os.path.join(current_dir, "_BPAReportTemplate.json")
294
+ with open(json_file_path, "r") as file:
295
+ report_json = json.load(file)
296
+
297
+ if len(dfR_filt) > 0:
298
+ update_report_from_reportjson(
299
+ report=report, report_json=report_json, workspace=dataset_workspace
300
+ )
301
+ else:
302
+ create_report_from_reportjson(
303
+ report=report,
304
+ dataset=dataset,
305
+ report_json=report_json,
306
+ workspace=dataset_workspace,
307
+ )
308
+
309
+
310
+ def _create_report(
311
+ report: str,
312
+ request_body: dict,
313
+ dataset: str,
314
+ dataset_workspace: Optional[str] = None,
315
+ report_workspace: Optional[str] = None,
316
+ update_if_exists: Optional[bool] = False,
317
+ ):
318
+
319
+ from sempy_labs.report import report_rebind
320
+
321
+ report_workspace = fabric.resolve_workspace_name(report_workspace)
322
+ report_workspace_id = fabric.resolve_workspace_id(report_workspace)
323
+ client = fabric.FabricRestClient()
324
+
325
+ dfR = fabric.list_reports(workspace=report_workspace)
326
+ dfR_filt = dfR[dfR["Name"] == report]
327
+
328
+ updated_report = False
329
+
330
+ # Create report if it does not exist
331
+ if len(dfR_filt) == 0:
332
+ response = client.post(
333
+ f"/v1/workspaces/{report_workspace_id}/reports",
334
+ json=request_body,
335
+ lro_wait=True,
336
+ )
337
+ if response.status_code not in [200, 201]:
338
+ raise FabricHTTPException(response)
339
+ print(
340
+ f"{icons.green_dot} The '{report}' report has been created within the '{report_workspace}'"
341
+ )
342
+ updated_report = True
343
+ # Update the report if it exists
344
+ elif len(dfR_filt) > 0 and update_if_exists:
345
+ report_id = dfR_filt["Id"].iloc[0]
346
+ response = client.post(
347
+ f"/v1/workspaces/{report_workspace_id}/reports/{report_id}/updateDefinition",
348
+ json=request_body,
349
+ lro_wait=True,
350
+ )
351
+ if response.status_code not in [200, 201]:
352
+ raise FabricHTTPException(response)
353
+ print(
354
+ f"{icons.green_dot} The '{report}' report has been updated within the '{report_workspace}'"
355
+ )
356
+ updated_report = True
357
+ else:
358
+ raise ValueError(
359
+ f"{icons.red_dot} The '{report}' report within the '{report_workspace}' workspace already exists and it was selected not to update it if the report already exists."
360
+ )
361
+
362
+ # Rebind the report to the semantic model to make sure it is pointed at the correct semantic model
363
+ if updated_report:
364
+ report_rebind(
365
+ report=report,
366
+ dataset=dataset,
367
+ report_workspace=report_workspace,
368
+ dataset_workspace=dataset_workspace,
369
+ )