semantic-link-labs 0.4.1__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 (52) hide show
  1. semantic_link_labs-0.4.1.dist-info/LICENSE +21 -0
  2. semantic_link_labs-0.4.1.dist-info/METADATA +22 -0
  3. semantic_link_labs-0.4.1.dist-info/RECORD +52 -0
  4. semantic_link_labs-0.4.1.dist-info/WHEEL +5 -0
  5. semantic_link_labs-0.4.1.dist-info/top_level.txt +1 -0
  6. sempy_labs/__init__.py +154 -0
  7. sempy_labs/_ai.py +496 -0
  8. sempy_labs/_clear_cache.py +39 -0
  9. sempy_labs/_connections.py +234 -0
  10. sempy_labs/_dax.py +70 -0
  11. sempy_labs/_generate_semantic_model.py +280 -0
  12. sempy_labs/_helper_functions.py +506 -0
  13. sempy_labs/_icons.py +4 -0
  14. sempy_labs/_list_functions.py +1372 -0
  15. sempy_labs/_model_auto_build.py +143 -0
  16. sempy_labs/_model_bpa.py +1354 -0
  17. sempy_labs/_model_dependencies.py +341 -0
  18. sempy_labs/_one_lake_integration.py +155 -0
  19. sempy_labs/_query_scale_out.py +447 -0
  20. sempy_labs/_refresh_semantic_model.py +184 -0
  21. sempy_labs/_tom.py +3766 -0
  22. sempy_labs/_translations.py +378 -0
  23. sempy_labs/_vertipaq.py +893 -0
  24. sempy_labs/directlake/__init__.py +45 -0
  25. sempy_labs/directlake/_directlake_schema_compare.py +110 -0
  26. sempy_labs/directlake/_directlake_schema_sync.py +128 -0
  27. sempy_labs/directlake/_fallback.py +62 -0
  28. sempy_labs/directlake/_get_directlake_lakehouse.py +69 -0
  29. sempy_labs/directlake/_get_shared_expression.py +59 -0
  30. sempy_labs/directlake/_guardrails.py +84 -0
  31. sempy_labs/directlake/_list_directlake_model_calc_tables.py +54 -0
  32. sempy_labs/directlake/_show_unsupported_directlake_objects.py +89 -0
  33. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +81 -0
  34. sempy_labs/directlake/_update_directlake_partition_entity.py +64 -0
  35. sempy_labs/directlake/_warm_cache.py +210 -0
  36. sempy_labs/lakehouse/__init__.py +24 -0
  37. sempy_labs/lakehouse/_get_lakehouse_columns.py +81 -0
  38. sempy_labs/lakehouse/_get_lakehouse_tables.py +250 -0
  39. sempy_labs/lakehouse/_lakehouse.py +85 -0
  40. sempy_labs/lakehouse/_shortcuts.py +296 -0
  41. sempy_labs/migration/__init__.py +29 -0
  42. sempy_labs/migration/_create_pqt_file.py +239 -0
  43. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +429 -0
  44. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +150 -0
  45. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +524 -0
  46. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +165 -0
  47. sempy_labs/migration/_migration_validation.py +227 -0
  48. sempy_labs/migration/_refresh_calc_tables.py +129 -0
  49. sempy_labs/report/__init__.py +35 -0
  50. sempy_labs/report/_generate_report.py +253 -0
  51. sempy_labs/report/_report_functions.py +855 -0
  52. sempy_labs/report/_report_rebind.py +131 -0
@@ -0,0 +1,447 @@
1
+ import sempy
2
+ import sempy.fabric as fabric
3
+ import pandas as pd
4
+ from sempy_labs._helper_functions import resolve_dataset_id
5
+ from typing import List, Optional, Union
6
+ import sempy_labs._icons as icons
7
+
8
+
9
+ def qso_sync(dataset: str, workspace: Optional[str] = None):
10
+ """
11
+ Triggers a query scale-out sync of read-only replicas for the specified dataset from the specified workspace.
12
+
13
+ Parameters
14
+ ----------
15
+ dataset : str
16
+ Name of the semantic model.
17
+ workspace : str, default=None
18
+ The Fabric workspace name.
19
+ Defaults to None which resolves to the workspace of the attached lakehouse
20
+ or if no lakehouse attached, resolves to the workspace of the notebook.
21
+
22
+ Returns
23
+ -------
24
+
25
+ """
26
+
27
+ # https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/trigger-query-scale-out-sync-in-group
28
+
29
+ if workspace is None:
30
+ workspace_id = fabric.get_workspace_id()
31
+ workspace = fabric.resolve_workspace_name(workspace_id)
32
+ else:
33
+ workspace_id = fabric.resolve_workspace_id(workspace)
34
+
35
+ dataset_id = resolve_dataset_id(dataset, workspace)
36
+
37
+ client = fabric.PowerBIRestClient()
38
+ response = client.post(
39
+ f"/v1.0/myorg/groups/{workspace_id}/datasets/{dataset_id}/queryScaleOut/sync"
40
+ )
41
+
42
+ if response.status_code == 200:
43
+ print(
44
+ f"{icons.green_dot} QSO sync initiated for the '{dataset}' semantic model within the '{workspace}' workspace."
45
+ )
46
+ else:
47
+ print(
48
+ f"{icons.red_dot} QSO sync failed for the '{dataset}' semantic model within the '{workspace}' workspace."
49
+ )
50
+
51
+
52
+ def qso_sync_status(dataset: str, workspace: Optional[str] = None):
53
+ """
54
+ Returns the query scale-out sync status for the specified dataset from the specified workspace.
55
+
56
+ Parameters
57
+ ----------
58
+ dataset : str
59
+ Name of the semantic model.
60
+ workspace : str, default=None
61
+ The Fabric workspace name.
62
+ Defaults to None which resolves to the workspace of the attached lakehouse
63
+ or if no lakehouse attached, resolves to the workspace of the notebook.
64
+
65
+ Returns
66
+ -------
67
+
68
+ """
69
+
70
+ # https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/get-query-scale-out-sync-status-in-group
71
+
72
+ df = pd.DataFrame(
73
+ columns=[
74
+ "Scale Out Status",
75
+ "Sync Start Time",
76
+ "Sync End Time",
77
+ "Commit Version",
78
+ "Commit Timestamp",
79
+ "Target Sync Version",
80
+ "Target Sync Timestamp",
81
+ "Trigger Reason",
82
+ "Min Active Read Version",
83
+ "Min Active Read Timestamp",
84
+ ]
85
+ )
86
+ dfRep = pd.DataFrame(
87
+ columns=["Replica ID", "Replica Type", "Replica Version", "Replica Timestamp"]
88
+ )
89
+
90
+ if workspace is None:
91
+ workspace_id = fabric.get_workspace_id()
92
+ workspace = fabric.resolve_workspace_name(workspace_id)
93
+ else:
94
+ workspace_id = fabric.resolve_workspace_id(workspace)
95
+
96
+ dataset_id = resolve_dataset_id(dataset, workspace)
97
+
98
+ client = fabric.PowerBIRestClient()
99
+ response = client.get(
100
+ f"/v1.0/myorg/groups/{workspace_id}/datasets/{dataset_id}/queryScaleOut/syncStatus"
101
+ )
102
+
103
+ if response.status_code == 200:
104
+ o = response.json()
105
+ sos = o["scaleOutStatus"]
106
+
107
+ if sos == "Enabled":
108
+ new_data = {
109
+ "Scale Out Status": o["scaleOutStatus"],
110
+ "Sync Start Time": o["syncStartTime"],
111
+ "Sync End Time": o["syncEndTime"],
112
+ "Commit Version": o["commitVersion"],
113
+ "Commit Timestamp": o["commitTimestamp"],
114
+ "Target Sync Version": o["targetSyncVersion"],
115
+ "Target Sync Timestamp": o["targetSyncTimestamp"],
116
+ "Trigger Reason": o["triggerReason"],
117
+ "Min Active Read Version": o["minActiveReadVersion"],
118
+ "Min Active Read Timestamp": o["minActiveReadTimestamp"],
119
+ }
120
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
121
+
122
+ for r in o["scaleOutReplicas"]:
123
+ new_data = {
124
+ "Replica ID": r["replicaId"],
125
+ "Replica Type": r["replicaType"],
126
+ "Replica Version": str(r["replicaVersion"]),
127
+ "Replica Timestamp": r["replicaTimestamp"],
128
+ }
129
+ dfRep = pd.concat(
130
+ [dfRep, pd.DataFrame(new_data, index=[0])], ignore_index=True
131
+ )
132
+
133
+ df["Sync Start Time"] = pd.to_datetime(df["Sync Start Time"])
134
+ df["Sync End Time"] = pd.to_datetime(df["Sync End Time"])
135
+ df["Commit Timestamp"] = pd.to_datetime(df["Commit Timestamp"])
136
+ df["Target Sync Timestamp"] = pd.to_datetime(df["Target Sync Timestamp"])
137
+ df["Min Active Read Timestamp"] = pd.to_datetime(
138
+ df["Min Active Read Timestamp"]
139
+ )
140
+ dfRep["Replica Timestamp"] = pd.to_datetime(dfRep["Replica Timestamp"])
141
+ df["Commit Version"] = df["Commit Version"].astype("int")
142
+ df["Target Sync Version"] = df["Target Sync Version"].astype("int")
143
+ df["Min Active Read Version"] = df["Min Active Read Version"].astype("int")
144
+
145
+ return df, dfRep
146
+ else:
147
+ print(f"{sos}\n\n")
148
+ return df, dfRep
149
+ else:
150
+ return response.status_code
151
+
152
+
153
+ def disable_qso(dataset: str, workspace: Optional[str] = None):
154
+ """
155
+ Sets the max read-only replicas to 0, disabling query scale out.
156
+
157
+ Parameters
158
+ ----------
159
+ dataset : str
160
+ Name of the semantic model.
161
+ workspace : str, default=None
162
+ The Fabric workspace name.
163
+ Defaults to None which resolves to the workspace of the attached lakehouse
164
+ or if no lakehouse attached, resolves to the workspace of the notebook.
165
+
166
+ Returns
167
+ -------
168
+
169
+ """
170
+
171
+ if workspace is None:
172
+ workspace_id = fabric.get_workspace_id()
173
+ workspace = fabric.resolve_workspace_name(workspace_id)
174
+ else:
175
+ workspace_id = fabric.resolve_workspace_id(workspace)
176
+
177
+ dataset_id = resolve_dataset_id(dataset, workspace)
178
+
179
+ request_body = {"queryScaleOutSettings": {"maxReadOnlyReplicas": "0"}}
180
+
181
+ client = fabric.PowerBIRestClient()
182
+ response = client.patch(
183
+ f"/v1.0/myorg/groups/{workspace_id}/datasets/{dataset_id}", json=request_body
184
+ )
185
+ if response.status_code == 200:
186
+ df = list_qso_settings(dataset=dataset, workspace=workspace)
187
+ print(
188
+ f"{icons.green_dot} Query scale out has been disabled for the '{dataset}' semantic model within the '{workspace}' workspace."
189
+ )
190
+ return df
191
+ else:
192
+ return f"{icons.red_dot} {response.status_code}"
193
+
194
+
195
+ def set_qso(
196
+ dataset: str,
197
+ auto_sync: Optional[bool] = True,
198
+ max_read_only_replicas: Optional[int] = -1,
199
+ workspace: Optional[str] = None,
200
+ ):
201
+ """
202
+ Sets the query scale out settings for a semantic model.
203
+
204
+ Parameters
205
+ ----------
206
+ dataset : str
207
+ Name of the semantic model.
208
+ auto_sync : bool, default=True
209
+ Whether the semantic model automatically syncs read-only replicas.
210
+ max_read_only_replicas : int, default=-1
211
+ To enable semantic model scale-out, set max_read_only_replicas to -1, or any non-0 value. A value of -1 allows Power BI to create as many read-only replicas as your Power BI capacity supports. You can also explicitly set the replica count to a value lower than that of the capacity maximum. Setting max_read_only_replicas to -1 is recommended.
212
+ workspace : str, default=None
213
+ The Fabric workspace name.
214
+ Defaults to None which resolves to the workspace of the attached lakehouse
215
+ or if no lakehouse attached, resolves to the workspace of the notebook.
216
+
217
+ Returns
218
+ -------
219
+
220
+ """
221
+
222
+ # https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/update-dataset-in-group
223
+
224
+ if workspace is None:
225
+ workspace_id = fabric.get_workspace_id()
226
+ workspace = fabric.resolve_workspace_name(workspace_id)
227
+ else:
228
+ workspace_id = fabric.resolve_workspace_id(workspace)
229
+
230
+ dataset_id = resolve_dataset_id(dataset, workspace)
231
+
232
+ if max_read_only_replicas == 0:
233
+ disable_qso(dataset=dataset, workspace=workspace)
234
+ return
235
+
236
+ request_body = {
237
+ "queryScaleOutSettings": {
238
+ "autoSyncReadOnlyReplicas": auto_sync,
239
+ "maxReadOnlyReplicas": str(max_read_only_replicas),
240
+ }
241
+ }
242
+
243
+ ssm = set_semantic_model_storage_format(
244
+ dataset=dataset, storage_format="Large", workspace=workspace
245
+ )
246
+ if ssm == 200:
247
+ client = fabric.PowerBIRestClient()
248
+ response = client.patch(
249
+ f"/v1.0/myorg/groups/{workspace_id}/datasets/{dataset_id}",
250
+ json=request_body,
251
+ )
252
+ if response.status_code == 200:
253
+ df = list_qso_settings(dataset=dataset, workspace=workspace)
254
+ print(
255
+ f"{icons.green_dot} Query scale out has been set on the '{dataset}' semantic model within the '{workspace}' workspace."
256
+ )
257
+ return df
258
+ else:
259
+ return f"{icons.red_dot} {response.status_code}"
260
+ else:
261
+ print(
262
+ f"{icons.red_dot} Failed to set the '{dataset}' semantic model within the '{workspace}' workspace to large semantic model storage format. This is a prerequisite for enabling Query Scale Out."
263
+ )
264
+ print(
265
+ "https://learn.microsoft.com/power-bi/enterprise/service-premium-scale-out#prerequisites"
266
+ )
267
+ return
268
+
269
+
270
+ def set_semantic_model_storage_format(
271
+ dataset: str, storage_format: str, workspace: Optional[str] = None
272
+ ):
273
+ """
274
+ Sets the semantic model storage format.
275
+
276
+ Parameters
277
+ ----------
278
+ dataset : str
279
+ Name of the semantic model.
280
+ storage_format : str
281
+ The storage format for the semantic model. Valid options: 'Large', 'Small'.
282
+ workspace : str, default=None
283
+ The Fabric workspace name.
284
+ Defaults to None which resolves to the workspace of the attached lakehouse
285
+ or if no lakehouse attached, resolves to the workspace of the notebook.
286
+
287
+ Returns
288
+ -------
289
+
290
+ """
291
+
292
+ if workspace is None:
293
+ workspace_id = fabric.get_workspace_id()
294
+ workspace = fabric.resolve_workspace_name(workspace_id)
295
+ else:
296
+ workspace_id = fabric.resolve_workspace_id(workspace)
297
+
298
+ dataset_id = resolve_dataset_id(dataset, workspace)
299
+
300
+ storage_format = storage_format.capitalize()
301
+
302
+ if storage_format == "Abf":
303
+ storage_format = "Small"
304
+ elif storage_format.startswith("Premium"):
305
+ storage_format = "Large"
306
+
307
+ storageFormats = ["Small", "Large"]
308
+
309
+ if storage_format == "Large":
310
+ request_body = {"targetStorageMode": "PremiumFiles"}
311
+ elif storage_format == "Small":
312
+ request_body = {"targetStorageMode": "Abf"}
313
+ else:
314
+ print(
315
+ f"{icons.red_dot} Invalid storage format value. Valid options: {storageFormats}."
316
+ )
317
+ return
318
+
319
+ client = fabric.PowerBIRestClient()
320
+ response = client.patch(
321
+ f"/v1.0/myorg/groups/{workspace_id}/datasets/{dataset_id}", json=request_body
322
+ )
323
+
324
+ if response.status_code == 200:
325
+ return print(
326
+ f"{icons.green_dot} Semantic model storage format set to '{storage_format}'."
327
+ )
328
+ else:
329
+ return f"{icons.red_dot} {response.status_code}"
330
+
331
+
332
+ def list_qso_settings(dataset: Optional[str] = None, workspace: Optional[str] = None):
333
+ """
334
+ Shows the query scale out settings for a semantic model (or all semantic models within a workspace).
335
+
336
+ Parameters
337
+ ----------
338
+ dataset : str, default=None
339
+ Name of the semantic model.
340
+ workspace : str, default=None
341
+ The Fabric workspace name.
342
+ Defaults to None which resolves to the workspace of the attached lakehouse
343
+ or if no lakehouse attached, resolves to the workspace of the notebook.
344
+
345
+ Returns
346
+ -------
347
+ pandas.DataFrame
348
+ A pandas dataframe showing the query scale out settings.
349
+ """
350
+
351
+ if workspace is None:
352
+ workspace_id = fabric.get_workspace_id()
353
+ workspace = fabric.resolve_workspace_name(workspace_id)
354
+ else:
355
+ workspace_id = fabric.resolve_workspace_id(workspace)
356
+
357
+ if dataset is not None:
358
+ dataset_id = resolve_dataset_id(dataset, workspace)
359
+
360
+ workspace_id = fabric.get_workspace_id()
361
+ df = pd.DataFrame(
362
+ columns=[
363
+ "Dataset Id",
364
+ "Dataset Name",
365
+ "Storage Mode",
366
+ "QSO Auto Sync Enabled",
367
+ "QSO Max Read Only Replicas",
368
+ ]
369
+ )
370
+ client = fabric.PowerBIRestClient()
371
+ response = client.get(f"/v1.0/myorg/groups/{workspace_id}/datasets")
372
+ for v in response.json()["value"]:
373
+ tsm = v["targetStorageMode"]
374
+ if tsm == "Abf":
375
+ sm = "Small"
376
+ else:
377
+ sm = "Large"
378
+ new_data = {
379
+ "Dataset Id": v["id"],
380
+ "Dataset Name": v["name"],
381
+ "Storage Mode": sm,
382
+ "QSO Auto Sync Enabled": v["queryScaleOutSettings"][
383
+ "autoSyncReadOnlyReplicas"
384
+ ],
385
+ "QSO Max Read Only Replicas": v["queryScaleOutSettings"][
386
+ "maxReadOnlyReplicas"
387
+ ],
388
+ }
389
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
390
+
391
+ df["QSO Auto Sync Enabled"] = df["QSO Auto Sync Enabled"].astype("bool")
392
+ df["QSO Max Read Only Replicas"] = df["QSO Max Read Only Replicas"].astype("int")
393
+
394
+ if dataset is not None:
395
+ df = df[df["Dataset Id"] == dataset_id]
396
+
397
+ return df
398
+
399
+
400
+ def set_workspace_default_storage_format(
401
+ storage_format: str, workspace: Optional[str] = None
402
+ ):
403
+ """
404
+ Sets the default storage format for semantic models within a workspace.
405
+
406
+ Parameters
407
+ ----------
408
+ storage_format : str
409
+ The storage format for the semantic model. Valid options: 'Large', 'Small'.
410
+ workspace : str, default=None
411
+ The Fabric workspace name.
412
+ Defaults to None which resolves to the workspace of the attached lakehouse
413
+ or if no lakehouse attached, resolves to the workspace of the notebook.
414
+
415
+ Returns
416
+ -------
417
+
418
+ """
419
+
420
+ # https://learn.microsoft.com/en-us/rest/api/power-bi/groups/update-group#defaultdatasetstorageformat
421
+
422
+ storageFormats = ["Small", "Large"]
423
+
424
+ storage_format = storage_format.capitalize()
425
+
426
+ if storage_format not in storageFormats:
427
+ print(
428
+ f"Invalid storage format. Please choose from these options: {storageFormats}."
429
+ )
430
+
431
+ if workspace is None:
432
+ workspace_id = fabric.get_workspace_id()
433
+ workspace = fabric.resolve_workspace_name(workspace_id)
434
+ else:
435
+ workspace_id = fabric.resolve_workspace_id(workspace)
436
+
437
+ request_body = {"name": workspace, "defaultDatasetStorageFormat": storage_format}
438
+
439
+ client = fabric.PowerBIRestClient()
440
+ response = client.patch(f"/v1.0/myorg/groups/{workspace_id}", json=request_body)
441
+
442
+ if response.status_code == 200:
443
+ print(
444
+ f"{icons.green_dot} The default storage format for the '{workspace}' workspace has been updated to '{storage_format}."
445
+ )
446
+ else:
447
+ print(f"{icons.red_dot} {response.status_code}")
@@ -0,0 +1,184 @@
1
+ import sempy
2
+ import sempy.fabric as fabric
3
+ import time
4
+ from sempy_labs._helper_functions import resolve_dataset_id
5
+ from typing import List, Optional, Union
6
+ from sempy._utils._log import log
7
+ import sempy_labs._icons as icons
8
+ from sempy_labs._helper_functions import resolve_workspace_name_and_id
9
+
10
+
11
+ @log
12
+ def refresh_semantic_model(
13
+ dataset: str,
14
+ tables: Optional[Union[str, List[str]]] = None,
15
+ partitions: Optional[Union[str, List[str]]] = None,
16
+ refresh_type: Optional[str] = None,
17
+ retry_count: Optional[int] = 0,
18
+ apply_refresh_policy: Optional[bool] = True,
19
+ workspace: Optional[str] = None,
20
+ ):
21
+ """
22
+ Refreshes a semantic model.
23
+
24
+ Parameters
25
+ ----------
26
+ dataset : str
27
+ Name of the semantic model.
28
+ tables : str, List[str], default=None
29
+ A string or a list of tables to refresh.
30
+ partitions: str, List[str], default=None
31
+ A string or a list of partitions to refresh. Partitions must be formatted as such: 'Table Name'[Partition Name].
32
+ refresh_type : str, default='full'
33
+ The type of processing to perform. Types align with the TMSL refresh command types: full, clearValues, calculate, dataOnly, automatic, and defragment. The add type isn't supported. Defaults to "full".
34
+ retry_count : int, default=0
35
+ Number of times the operation retries before failing.
36
+ apply_refresh_policy : bool, default=True
37
+ If an incremental refresh policy is defined, determines whether to apply the policy. Modes are true or false. If the policy isn't applied, the full process leaves partition definitions unchanged, and fully refreshes all partitions in the table. If commitMode is transactional, applyRefreshPolicy can be true or false. If commitMode is partialBatch, applyRefreshPolicy of true isn't supported, and applyRefreshPolicy must be set to false.
38
+ workspace : str, default=None
39
+ The Fabric workspace name.
40
+ Defaults to None which resolves to the workspace of the attached lakehouse
41
+ or if no lakehouse attached, resolves to the workspace of the notebook.
42
+ """
43
+
44
+ if workspace == None:
45
+ workspace_id = fabric.get_workspace_id()
46
+ workspace = fabric.resolve_workspace_name(workspace_id)
47
+
48
+ if refresh_type is None:
49
+ refresh_type = "full"
50
+
51
+ if isinstance(tables, str):
52
+ tables = [tables]
53
+ if isinstance(partitions, str):
54
+ partitions = [partitions]
55
+
56
+ objects = []
57
+
58
+ if tables is not None:
59
+ objects = objects + [{"table": table} for table in tables]
60
+ if partitions is not None:
61
+
62
+ def extract_names(partition):
63
+ parts = partition.split("[")
64
+ table_name = parts[0].strip("'")
65
+ partition_name = parts[1].strip("]")
66
+ return {"table": table_name, "partition": partition_name}
67
+
68
+ objects = objects + [extract_names(partition) for partition in partitions]
69
+
70
+ refresh_type = (
71
+ refresh_type.lower().replace("only", "Only").replace("values", "Values")
72
+ )
73
+
74
+ refreshTypes = [
75
+ "full",
76
+ "automatic",
77
+ "dataOnly",
78
+ "calculate",
79
+ "clearValues",
80
+ "defragment",
81
+ ]
82
+
83
+ if refresh_type not in refreshTypes:
84
+ print(
85
+ f"{icons.red_dot} Invalid refresh type. Refresh type must be one of these values: {refreshTypes}."
86
+ )
87
+ return
88
+
89
+ if len(objects) == 0:
90
+ requestID = fabric.refresh_dataset(
91
+ dataset=dataset,
92
+ workspace=workspace,
93
+ refresh_type=refresh_type,
94
+ retry_count=retry_count,
95
+ apply_refresh_policy=apply_refresh_policy,
96
+ )
97
+ else:
98
+ requestID = fabric.refresh_dataset(
99
+ dataset=dataset,
100
+ workspace=workspace,
101
+ refresh_type=refresh_type,
102
+ retry_count=retry_count,
103
+ apply_refresh_policy=apply_refresh_policy,
104
+ objects=objects,
105
+ )
106
+ print(
107
+ f"{icons.in_progress} Refresh of the '{dataset}' semantic model within the '{workspace}' workspace is in progress..."
108
+ )
109
+ if len(objects) != 0:
110
+ print(objects)
111
+
112
+ while True:
113
+ requestDetails = fabric.get_refresh_execution_details(
114
+ dataset=dataset, refresh_request_id=requestID, workspace=workspace
115
+ )
116
+ status = requestDetails.status
117
+
118
+ # Check if the refresh has completed
119
+ if status == "Completed":
120
+ break
121
+ elif status == "Failed":
122
+ print(
123
+ f"{icons.red_dot} The refresh of the '{dataset}' semantic model within the '{workspace}' workspace has failed."
124
+ )
125
+ return
126
+ elif status == "Cancelled":
127
+ print(
128
+ f"{icons.yellow_dot} The refresh of the '{dataset}' semantic model within the '{workspace}' workspace has been cancelled."
129
+ )
130
+ return
131
+
132
+ time.sleep(3)
133
+
134
+ print(
135
+ f"{icons.green_dot} Refresh of the '{dataset}' semantic model within the '{workspace}' workspace is complete."
136
+ )
137
+
138
+
139
+ @log
140
+ def cancel_dataset_refresh(
141
+ dataset: str, request_id: Optional[str] = None, workspace: Optional[str] = None
142
+ ):
143
+ """
144
+ Cancels the refresh of a semantic model which was executed via the `Enhanced Refresh API <https://learn.microsoft.com/power-bi/connect-data/asynchronous-refresh>`_
145
+
146
+ Parameters
147
+ ----------
148
+ dataset : str
149
+ Name of the semantic model.
150
+ request_id : str, default=None
151
+ The request id of a semantic model refresh.
152
+ Defaults to finding the latest active refresh of the semantic model.
153
+ workspace : str, default=None
154
+ The Fabric workspace name.
155
+ Defaults to None which resolves to the workspace of the attached lakehouse
156
+ or if no lakehouse attached, resolves to the workspace of the notebook.
157
+ """
158
+
159
+ (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
160
+
161
+ rr = fabric.list_refresh_requests(dataset=dataset, workspace=workspace)
162
+ rr_filt = rr[rr["Status"] == "Unknown"]
163
+
164
+ if request_id == None:
165
+ if len(rr_filt) == 0:
166
+ print(
167
+ f"{icons.red_dot} There are no active Enhanced API refreshes of the '{dataset}' semantic model within the '{workspace}' workspace."
168
+ )
169
+ return
170
+ request_id = rr_filt["Request Id"].iloc[0]
171
+
172
+ dataset_id = resolve_dataset_id(dataset=dataset, workspace=workspace)
173
+
174
+ client = fabric.PowerBIRestClient()
175
+
176
+ response = client.delete(
177
+ f"/v1.0/myorg/groups/{workspace_id}/datasets/{dataset_id}/refreshes/{request_id}"
178
+ )
179
+ if response.status_code == 200:
180
+ print(
181
+ f"{icons.green_dot} The '{request_id}' refresh request for the '{dataset}' semantic model within the '{workspace}' workspace has been cancelled."
182
+ )
183
+ else:
184
+ print(response.status_code)