semantic-link-labs 0.4.2__py3-none-any.whl → 0.5.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 (44) hide show
  1. {semantic_link_labs-0.4.2.dist-info → semantic_link_labs-0.5.0.dist-info}/METADATA +1 -1
  2. semantic_link_labs-0.5.0.dist-info/RECORD +53 -0
  3. {semantic_link_labs-0.4.2.dist-info → semantic_link_labs-0.5.0.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +27 -3
  5. sempy_labs/_ai.py +12 -32
  6. sempy_labs/_clear_cache.py +1 -3
  7. sempy_labs/_connections.py +39 -38
  8. sempy_labs/_generate_semantic_model.py +9 -14
  9. sempy_labs/_helper_functions.py +3 -12
  10. sempy_labs/_icons.py +1 -0
  11. sempy_labs/_list_functions.py +915 -391
  12. sempy_labs/_model_auto_build.py +2 -4
  13. sempy_labs/_model_bpa.py +26 -30
  14. sempy_labs/_model_dependencies.py +7 -13
  15. sempy_labs/_one_lake_integration.py +2 -5
  16. sempy_labs/_query_scale_out.py +12 -30
  17. sempy_labs/_refresh_semantic_model.py +5 -15
  18. sempy_labs/_translations.py +1 -1
  19. sempy_labs/_vertipaq.py +3 -10
  20. sempy_labs/directlake/_directlake_schema_compare.py +3 -9
  21. sempy_labs/directlake/_directlake_schema_sync.py +2 -6
  22. sempy_labs/directlake/_fallback.py +2 -6
  23. sempy_labs/directlake/_get_shared_expression.py +3 -9
  24. sempy_labs/directlake/_guardrails.py +3 -5
  25. sempy_labs/directlake/_list_directlake_model_calc_tables.py +3 -4
  26. sempy_labs/directlake/_show_unsupported_directlake_objects.py +1 -2
  27. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +3 -7
  28. sempy_labs/directlake/_update_directlake_partition_entity.py +2 -8
  29. sempy_labs/directlake/_warm_cache.py +5 -8
  30. sempy_labs/lakehouse/_get_lakehouse_columns.py +1 -1
  31. sempy_labs/lakehouse/_get_lakehouse_tables.py +3 -5
  32. sempy_labs/lakehouse/_lakehouse.py +1 -3
  33. sempy_labs/lakehouse/_shortcuts.py +2 -5
  34. sempy_labs/migration/_create_pqt_file.py +4 -13
  35. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +2 -6
  36. sempy_labs/migration/_migration_validation.py +4 -0
  37. sempy_labs/migration/_refresh_calc_tables.py +2 -0
  38. sempy_labs/report/_generate_report.py +2 -6
  39. sempy_labs/report/_report_functions.py +30 -73
  40. sempy_labs/report/_report_rebind.py +39 -39
  41. sempy_labs/tom/_model.py +141 -183
  42. semantic_link_labs-0.4.2.dist-info/RECORD +0 -53
  43. {semantic_link_labs-0.4.2.dist-info → semantic_link_labs-0.5.0.dist-info}/LICENSE +0 -0
  44. {semantic_link_labs-0.4.2.dist-info → semantic_link_labs-0.5.0.dist-info}/top_level.txt +0 -0
@@ -41,9 +41,7 @@ def model_auto_build(
41
41
 
42
42
  """
43
43
 
44
- if workspace is None:
45
- workspace_id = fabric.get_workspace_id()
46
- workspace = fabric.resolve_workspace_name(workspace_id)
44
+ workspace = fabric.resolve_workspace_name(workspace)
47
45
 
48
46
  if lakehouse_workspace is None:
49
47
  lakehouse_workspace = workspace
@@ -60,7 +58,7 @@ def model_auto_build(
60
58
 
61
59
  create_blank_semantic_model(dataset=dataset, workspace=workspace)
62
60
 
63
- with connect_semantic_model(dataset=dataset, workspace=workspace) as tom:
61
+ with connect_semantic_model(dataset=dataset, workspace=workspace, readonly=False) as tom:
64
62
 
65
63
  # DL Only
66
64
  expr = get_shared_expression(lakehouse=lakehouse, workspace=lakehouse_workspace)
sempy_labs/_model_bpa.py CHANGED
@@ -11,7 +11,7 @@ from sempy_labs.lakehouse._get_lakehouse_tables import get_lakehouse_tables
11
11
  from sempy_labs.lakehouse._lakehouse import lakehouse_attached
12
12
  from typing import List, Optional, Union
13
13
  from sempy._utils._log import log
14
-
14
+ import sempy_labs._icons as icons
15
15
 
16
16
  def model_bpa_rules():
17
17
  """
@@ -70,8 +70,8 @@ def model_bpa_rules():
70
70
  "Table",
71
71
  "Warning",
72
72
  "Avoid using many-to-many relationships on tables used for dynamic row level security",
73
- lambda df: (df["Used in M2M Relationship"] is True)
74
- & (df["Used in Dynamic RLS"] is True),
73
+ lambda df: (df["Used in M2M Relationship"] == True)
74
+ & (df["Used in Dynamic RLS"] == True),
75
75
  "Using many-to-many relationships on tables which use dynamic row level security can cause serious query performance degradation. This pattern's performance problems compound when snowflaking multiple many-to-many relationships against a table which contains row level security. Instead, use one of the patterns shown in the article below where a single dimension table relates many-to-one to a security table.",
76
76
  "https://www.elegantbi.com/post/dynamicrlspatterns",
77
77
  ),
@@ -88,12 +88,12 @@ def model_bpa_rules():
88
88
  "Column",
89
89
  "Warning",
90
90
  "Set IsAvailableInMdx to false on non-attribute columns",
91
- lambda df: (df["Is Direct Lake"] is False)
92
- & (df["Is Available in MDX"] is True)
93
- & ((df["Hidden"] is True) | (df["Parent Is Hidden"] is True))
94
- & (df["Used in Sort By"] is False)
95
- & (df["Used in Hierarchy"] is False)
96
- & (df["Sort By Column"] is None),
91
+ lambda df: (df["Is Direct Lake"] == False)
92
+ & (df["Is Available in MDX"] == True)
93
+ & ((df["Hidden"] == True) | (df["Parent Is Hidden"] == True))
94
+ & (df["Used in Sort By"] == False)
95
+ & (df["Used in Hierarchy"] == False)
96
+ & (df["Sort By Column"] == None),
97
97
  "To speed up processing time and conserve memory after processing, attribute hierarchies should not be built for columns that are never used for slicing by MDX clients. In other words, all hidden columns that are not used as a Sort By Column or referenced in user hierarchies should have their IsAvailableInMdx property set to false. The IsAvailableInMdx property is not relevant for Direct Lake models.",
98
98
  "https://blog.crossjoin.co.uk/2018/07/02/isavailableinmdx-ssas-tabular",
99
99
  ),
@@ -219,7 +219,7 @@ def model_bpa_rules():
219
219
  "Table",
220
220
  "Warning",
221
221
  "Large tables should be partitioned",
222
- lambda df: (df["Is Direct Lake"] is False)
222
+ lambda df: (df["Is Direct Lake"] == False)
223
223
  & (df["Partition Count"] == 1)
224
224
  & (df["Row Count"] > 25000000),
225
225
  "Large tables should be partitioned in order to optimize processing. This is not relevant for semantic models in Direct Lake mode as they can only have one partition per table.",
@@ -306,11 +306,11 @@ def model_bpa_rules():
306
306
  "Column",
307
307
  "Warning",
308
308
  "Set IsAvailableInMdx to true on necessary columns",
309
- lambda df: (df["Is Direct Lake"] is False)
310
- & (df["Is Available in MDX"] is False)
309
+ lambda df: (df["Is Direct Lake"] == False)
310
+ & (df["Is Available in MDX"] == False)
311
311
  & (
312
- (df["Used in Sort By"] is True)
313
- | (df["Used in Hierarchy"] is True)
312
+ (df["Used in Sort By"] == True)
313
+ | (df["Used in Hierarchy"] == True)
314
314
  | (df["Sort By Column"] != None)
315
315
  ),
316
316
  "In order to avoid errors, ensure that attribute hierarchies are enabled if a column is used for sorting another column, used in a hierarchy, used in variations, or is sorted by another column. The IsAvailableInMdx property is not relevant for Direct Lake models.",
@@ -320,8 +320,8 @@ def model_bpa_rules():
320
320
  "Table",
321
321
  "Error",
322
322
  "Avoid the USERELATIONSHIP function and RLS against the same table",
323
- lambda df: (df["USERELATIONSHIP Used"] is True)
324
- & (df["Used in RLS"] is True),
323
+ lambda df: (df["USERELATIONSHIP Used"] == True)
324
+ & (df["Used in RLS"] == True),
325
325
  "The USERELATIONSHIP function may not be used against a table which also leverages row-level security (RLS). This will generate an error when using the particular measure in a visual. This rule will highlight the table which is used in a measure's USERELATIONSHIP function as well as RLS.",
326
326
  "https://blog.crossjoin.co.uk/2013/05/10/userelationship-and-tabular-row-security",
327
327
  ),
@@ -494,7 +494,7 @@ def model_bpa_rules():
494
494
  "Table",
495
495
  "Warning",
496
496
  "Ensure tables have relationships",
497
- lambda df: (df["Used in Relationship"] is False)
497
+ lambda df: (df["Used in Relationship"] == False)
498
498
  & (df["Type"] != "Calculation Group"),
499
499
  "This rule highlights tables which are not connected to any other table in the model with a relationship.",
500
500
  ),
@@ -511,7 +511,7 @@ def model_bpa_rules():
511
511
  "Column",
512
512
  "Info",
513
513
  "Visible objects with no description",
514
- lambda df: (df["Hidden"] is False) & (df["Description"].str.len() == 0),
514
+ lambda df: (df["Hidden"] == False) & (df["Description"].str.len() == 0),
515
515
  "Calculation groups have no function unless they have calculation items.",
516
516
  ),
517
517
  (
@@ -595,7 +595,7 @@ def model_bpa_rules():
595
595
  "Column",
596
596
  "Info",
597
597
  "Hide foreign keys",
598
- lambda df: (df["Foreign Key"]) & (df["Hidden"] is False),
598
+ lambda df: (df["Foreign Key"]) & (df["Hidden"] == False),
599
599
  "Foreign keys should always be hidden.",
600
600
  ),
601
601
  (
@@ -603,7 +603,7 @@ def model_bpa_rules():
603
603
  "Column",
604
604
  "Info",
605
605
  "Mark primary keys",
606
- lambda df: (df["Primary Key"]) & (df["Key"] is False),
606
+ lambda df: (df["Primary Key"]) & (df["Key"] == False),
607
607
  "Set the 'Key' property to 'True' for primary key columns within the column properties.",
608
608
  ),
609
609
  (
@@ -744,9 +744,7 @@ def run_model_bpa(
744
744
  message="This pattern is interpreted as a regular expression, and has match groups.",
745
745
  )
746
746
 
747
- if workspace is None:
748
- workspace_id = fabric.get_workspace_id()
749
- workspace = fabric.resolve_workspace_name(workspace_id)
747
+ workspace = fabric.resolve_workspace_name(workspace)
750
748
 
751
749
  if rules_dataframe is None:
752
750
  rules_dataframe = model_bpa_rules()
@@ -951,7 +949,7 @@ def run_model_bpa(
951
949
  dfD["Has Date Table"] = any(
952
950
  (r["Parent Data Category"] == "Time")
953
951
  & (r["Data Type"] == "DateTime")
954
- & (r["Key"] is True)
952
+ & (r["Key"] == True)
955
953
  for i, r in dfC.iterrows()
956
954
  )
957
955
  # dfC['In Date Table'] = dfC['Table Name'].isin(dfT.loc[dfT['Data Category'] == "Time", 'Name'])
@@ -1033,7 +1031,7 @@ def run_model_bpa(
1033
1031
  dfM.at[i, "Has Fully Qualified Measure Reference"] = True
1034
1032
 
1035
1033
  dfR["Inactive without USERELATIONSHIP"] = False
1036
- for i, r in dfR[dfR["Active"] is False].iterrows():
1034
+ for i, r in dfR[dfR["Active"] == False].iterrows():
1037
1035
  fromTable = r["From Table"]
1038
1036
  fromColumn = r["From Column"]
1039
1037
  toTable = r["To Table"]
@@ -1184,10 +1182,8 @@ def run_model_bpa(
1184
1182
  if export:
1185
1183
  lakeAttach = lakehouse_attached()
1186
1184
  if lakeAttach is False:
1187
- print(
1188
- f"In order to save the Best Practice Analyzer results, a lakehouse must be attached to the notebook. Please attach a lakehouse to this notebook."
1189
- )
1190
- return
1185
+ raise ValueError(f"{icons.red_dot} In order to save the Best Practice Analyzer results, a lakehouse must be attached to the notebook. Please attach a lakehouse to this notebook.")
1186
+
1191
1187
  dfExport = finalDF.copy()
1192
1188
  delta_table_name = "modelbparesults"
1193
1189
 
@@ -1230,7 +1226,7 @@ def run_model_bpa(
1230
1226
  spark_df = spark.createDataFrame(dfExport)
1231
1227
  spark_df.write.mode("append").format("delta").saveAsTable(delta_table_name)
1232
1228
  print(
1233
- f"\u2022 Model Best Practice Analyzer results for the '{dataset}' semantic model have been appended to the '{delta_table_name}' delta table."
1229
+ f"{icons.green_dot} Model Best Practice Analyzer results for the '{dataset}' semantic model have been appended to the '{delta_table_name}' delta table."
1234
1230
  )
1235
1231
 
1236
1232
  if return_dataframe:
@@ -25,9 +25,7 @@ def get_measure_dependencies(dataset: str, workspace: Optional[str] = None):
25
25
  Shows all dependencies for all measures in the semantic model.
26
26
  """
27
27
 
28
- if workspace is None:
29
- workspace_id = fabric.get_workspace_id()
30
- workspace = fabric.resolve_workspace_name(workspace_id)
28
+ workspace = fabric.resolve_workspace_name(workspace)
31
29
 
32
30
  dep = fabric.evaluate_dax(
33
31
  dataset=dataset,
@@ -63,11 +61,11 @@ def get_measure_dependencies(dataset: str, workspace: Optional[str] = None):
63
61
  axis=1,
64
62
  )
65
63
 
66
- while any(df["Done"] is False):
64
+ while any(df["Done"] == False):
67
65
  for i, r in df.iterrows():
68
66
  rObjFull = r["Referenced Full Object Name"]
69
67
  rObj = r["Referenced Object"]
70
- if r["Done"] is False:
68
+ if r["Done"] == False:
71
69
  dep_filt = dep[dep["Full Object Name"] == rObjFull]
72
70
 
73
71
  for index, dependency in dep_filt.iterrows():
@@ -150,9 +148,7 @@ def get_model_calc_dependencies(dataset: str, workspace: Optional[str] = None):
150
148
  Shows all dependencies for all objects in the semantic model.
151
149
  """
152
150
 
153
- if workspace is None:
154
- workspace_id = fabric.get_workspace_id()
155
- workspace = fabric.resolve_workspace_name(workspace_id)
151
+ workspace = fabric.resolve_workspace_name(workspace)
156
152
 
157
153
  dep = fabric.evaluate_dax(
158
154
  dataset=dataset,
@@ -191,11 +187,11 @@ def get_model_calc_dependencies(dataset: str, workspace: Optional[str] = None):
191
187
  lambda row: False if row["Referenced Object Type"] in objs else True, axis=1
192
188
  )
193
189
 
194
- while any(df["Done"] is False):
190
+ while any(df["Done"] == False):
195
191
  for i, r in df.iterrows():
196
192
  rObjFull = r["Referenced Full Object Name"]
197
193
  rObj = r["Referenced Object"]
198
- if r["Done"] is False:
194
+ if r["Done"] == False:
199
195
  dep_filt = dep[dep["Full Object Name"] == rObjFull]
200
196
 
201
197
  for index, dependency in dep_filt.iterrows():
@@ -282,9 +278,7 @@ def measure_dependency_tree(
282
278
 
283
279
  """
284
280
 
285
- if workspace is None:
286
- workspace_id = fabric.get_workspace_id()
287
- workspace = fabric.resolve_workspace_name(workspace_id)
281
+ workspace = fabric.resolve_workspace_name(workspace)
288
282
 
289
283
  dfM = fabric.list_measures(dataset=dataset, workspace=workspace)
290
284
  dfM_filt = dfM[dfM["Measure Name"] == measure_name]
@@ -42,10 +42,7 @@ def export_model_to_onelake(
42
42
  dfD_filt = dfD[dfD["Dataset Name"] == dataset]
43
43
 
44
44
  if len(dfD_filt) == 0:
45
- print(
46
- f"{icons.red_dot} The '{dataset}' semantic model does not exist in the '{workspace}' workspace."
47
- )
48
- return
45
+ raise ValueError(f"{icons.red_dot} The '{dataset}' semantic model does not exist in the '{workspace}' workspace.")
49
46
 
50
47
  tmsl = f"""
51
48
  {{
@@ -104,7 +101,7 @@ def export_model_to_onelake(
104
101
  dfP_filt = dfP[
105
102
  (dfP["Mode"] == "Import")
106
103
  & (dfP["Source Type"] != "CalculationGroup")
107
- & (dfP["Parent System Managed"] is False)
104
+ & (dfP["Parent System Managed"] == False)
108
105
  ]
109
106
  dfC = fabric.list_columns(dataset=dataset, workspace=workspace)
110
107
  tmc = pd.DataFrame(dfP.groupby("Table Name")["Mode"].nunique()).reset_index()
@@ -44,10 +44,7 @@ def qso_sync(dataset: str, workspace: Optional[str] = None):
44
44
  f"{icons.green_dot} QSO sync initiated for the '{dataset}' semantic model within the '{workspace}' workspace."
45
45
  )
46
46
  else:
47
- print(
48
- f"{icons.red_dot} QSO sync failed for the '{dataset}' semantic model within the '{workspace}' workspace."
49
- )
50
-
47
+ raise ValueError(f"{icons.red_dot} QSO sync failed for the '{dataset}' semantic model within the '{workspace}' workspace.")
51
48
 
52
49
  def qso_sync_status(dataset: str, workspace: Optional[str] = None):
53
50
  """
@@ -189,7 +186,7 @@ def disable_qso(dataset: str, workspace: Optional[str] = None):
189
186
  )
190
187
  return df
191
188
  else:
192
- return f"{icons.red_dot} {response.status_code}"
189
+ raise ValueError(f"{icons.red_dot} {response.status_code}")
193
190
 
194
191
 
195
192
  def set_qso(
@@ -256,16 +253,9 @@ def set_qso(
256
253
  )
257
254
  return df
258
255
  else:
259
- return f"{icons.red_dot} {response.status_code}"
256
+ raise ValueError(f"{icons.red_dot} {response.status_code}")
260
257
  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
-
258
+ raise ValueError(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.\n\"https://learn.microsoft.com/power-bi/enterprise/service-premium-scale-out#prerequisites\"")
269
259
 
270
260
  def set_semantic_model_storage_format(
271
261
  dataset: str, storage_format: str, workspace: Optional[str] = None
@@ -311,10 +301,7 @@ def set_semantic_model_storage_format(
311
301
  elif storage_format == "Small":
312
302
  request_body = {"targetStorageMode": "Abf"}
313
303
  else:
314
- print(
315
- f"{icons.red_dot} Invalid storage format value. Valid options: {storageFormats}."
316
- )
317
- return
304
+ raise ValueError(f"{icons.red_dot} Invalid storage format value. Valid options: {storageFormats}.")
318
305
 
319
306
  client = fabric.PowerBIRestClient()
320
307
  response = client.patch(
@@ -326,8 +313,7 @@ def set_semantic_model_storage_format(
326
313
  f"{icons.green_dot} Semantic model storage format set to '{storage_format}'."
327
314
  )
328
315
  else:
329
- return f"{icons.red_dot} {response.status_code}"
330
-
316
+ raise ValueError(f"{icons.red_dot} {response.status_code}")
331
317
 
332
318
  def list_qso_settings(dataset: Optional[str] = None, workspace: Optional[str] = None):
333
319
  """
@@ -370,21 +356,17 @@ def list_qso_settings(dataset: Optional[str] = None, workspace: Optional[str] =
370
356
  client = fabric.PowerBIRestClient()
371
357
  response = client.get(f"/v1.0/myorg/groups/{workspace_id}/datasets")
372
358
  for v in response.json()["value"]:
373
- tsm = v["targetStorageMode"]
359
+ tsm = v.get("targetStorageMode")
374
360
  if tsm == "Abf":
375
361
  sm = "Small"
376
362
  else:
377
363
  sm = "Large"
378
364
  new_data = {
379
- "Dataset Id": v["id"],
380
- "Dataset Name": v["name"],
365
+ "Dataset Id": v.get("id"),
366
+ "Dataset Name": v.get("name"),
381
367
  "Storage Mode": sm,
382
- "QSO Auto Sync Enabled": v["queryScaleOutSettings"][
383
- "autoSyncReadOnlyReplicas"
384
- ],
385
- "QSO Max Read Only Replicas": v["queryScaleOutSettings"][
386
- "maxReadOnlyReplicas"
387
- ],
368
+ "QSO Auto Sync Enabled": v.get("queryScaleOutSettings",{}).get("autoSyncReadOnlyReplicas"),
369
+ "QSO Max Read Only Replicas": v.get("queryScaleOutSettings",{}).get("maxReadOnlyReplicas"),
388
370
  }
389
371
  df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
390
372
 
@@ -444,4 +426,4 @@ def set_workspace_default_storage_format(
444
426
  f"{icons.green_dot} The default storage format for the '{workspace}' workspace has been updated to '{storage_format}."
445
427
  )
446
428
  else:
447
- print(f"{icons.red_dot} {response.status_code}")
429
+ raise ValueError(f"{icons.red_dot} {response.status_code}")
@@ -41,9 +41,7 @@ def refresh_semantic_model(
41
41
  or if no lakehouse attached, resolves to the workspace of the notebook.
42
42
  """
43
43
 
44
- if workspace is None:
45
- workspace_id = fabric.get_workspace_id()
46
- workspace = fabric.resolve_workspace_name(workspace_id)
44
+ workspace = fabric.resolve_workspace_name(workspace)
47
45
 
48
46
  if refresh_type is None:
49
47
  refresh_type = "full"
@@ -81,10 +79,7 @@ def refresh_semantic_model(
81
79
  ]
82
80
 
83
81
  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
82
+ raise ValueError(f"{icons.red_dot} Invalid refresh type. Refresh type must be one of these values: {refreshTypes}.")
88
83
 
89
84
  if len(objects) == 0:
90
85
  requestID = fabric.refresh_dataset(
@@ -119,10 +114,7 @@ def refresh_semantic_model(
119
114
  if status == "Completed":
120
115
  break
121
116
  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
117
+ raise ValueError(f"{icons.red_dot} The refresh of the '{dataset}' semantic model within the '{workspace}' workspace has failed.")
126
118
  elif status == "Cancelled":
127
119
  print(
128
120
  f"{icons.yellow_dot} The refresh of the '{dataset}' semantic model within the '{workspace}' workspace has been cancelled."
@@ -163,10 +155,8 @@ def cancel_dataset_refresh(
163
155
 
164
156
  if request_id is None:
165
157
  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
158
+ raise ValueError(f"{icons.red_dot} There are no active Enhanced API refreshes of the '{dataset}' semantic model within the '{workspace}' workspace.")
159
+
170
160
  request_id = rr_filt["Request Id"].iloc[0]
171
161
 
172
162
  dataset_id = resolve_dataset_id(dataset=dataset, workspace=workspace)
@@ -35,7 +35,7 @@ def translate_semantic_model(
35
35
  from synapse.ml.services import Translate
36
36
  from pyspark.sql.functions import col, flatten
37
37
  from pyspark.sql import SparkSession
38
- from .tom import connect_semantic_model
38
+ from sempy_labs.tom import connect_semantic_model
39
39
 
40
40
  if isinstance(languages, str):
41
41
  languages = [languages]
sempy_labs/_vertipaq.py CHANGED
@@ -56,9 +56,7 @@ def vertipaq_analyzer(
56
56
  "ignore", message="createDataFrame attempted Arrow optimization*"
57
57
  )
58
58
 
59
- if workspace is None:
60
- workspace_id = fabric.get_workspace_id()
61
- workspace = fabric.resolve_workspace_name(workspace_id)
59
+ workspace = fabric.resolve_workspace_name(workspace)
62
60
 
63
61
  if lakehouse_workspace is None:
64
62
  lakehouse_workspace = workspace
@@ -102,9 +100,7 @@ def vertipaq_analyzer(
102
100
  dfI_filt = dfI[(dfI["Id"] == sqlEndpointId)]
103
101
 
104
102
  if len(dfI_filt) == 0:
105
- print(
106
- f"{icons.red_dot} The lakehouse (SQL Endpoint) used by the '{dataset}' semantic model does not reside in the '{lakehouse_workspace}' workspace. Please update the lakehouse_workspace parameter."
107
- )
103
+ raise ValueError(f"{icons.red_dot} The lakehouse (SQL Endpoint) used by the '{dataset}' semantic model does not reside in the '{lakehouse_workspace}' workspace. Please update the lakehouse_workspace parameter.")
108
104
  else:
109
105
  lakehouseName = dfI_filt["Display Name"].iloc[0]
110
106
 
@@ -437,10 +433,7 @@ def vertipaq_analyzer(
437
433
  if export in ["table", "zip"]:
438
434
  lakeAttach = lakehouse_attached()
439
435
  if lakeAttach is False:
440
- print(
441
- f"{icons.red_dot} In order to save the Vertipaq Analyzer results, a lakehouse must be attached to the notebook. Please attach a lakehouse to this notebook."
442
- )
443
- return
436
+ raise ValueError(f"{icons.red_dot} In order to save the Vertipaq Analyzer results, a lakehouse must be attached to the notebook. Please attach a lakehouse to this notebook.")
444
437
 
445
438
  if export == "table":
446
439
  spark = SparkSession.builder.getOrCreate()
@@ -40,9 +40,7 @@ def direct_lake_schema_compare(
40
40
  or if no lakehouse attached, resolves to the workspace of the notebook.
41
41
  """
42
42
 
43
- if workspace is None:
44
- workspace_id = fabric.get_workspace_id()
45
- workspace = fabric.resolve_workspace_name(workspace_id)
43
+ workspace = fabric.resolve_workspace_name(workspace)
46
44
 
47
45
  if lakehouse_workspace is None:
48
46
  lakehouse_workspace = workspace
@@ -57,14 +55,10 @@ def direct_lake_schema_compare(
57
55
  dfI_filt = dfI[(dfI["Id"] == sqlEndpointId)]
58
56
 
59
57
  if len(dfI_filt) == 0:
60
- print(
61
- f"{icons.red_dot} The SQL Endpoint in the '{dataset}' semantic model in the '{workspace} workspace does not point to the '{lakehouse}' lakehouse in the '{lakehouse_workspace}' workspace as specified."
62
- )
63
- return
58
+ raise ValueError(f"{icons.red_dot} The SQL Endpoint in the '{dataset}' semantic model in the '{workspace} workspace does not point to the '{lakehouse}' lakehouse in the '{lakehouse_workspace}' workspace as specified.")
64
59
 
65
60
  if not any(r["Mode"] == "DirectLake" for i, r in dfP.iterrows()):
66
- print(f"{icons.red_dot} The '{dataset}' semantic model is not in Direct Lake mode.")
67
- return
61
+ raise ValueError(f"{icons.red_dot} The '{dataset}' semantic model is not in Direct Lake mode.")
68
62
 
69
63
  dfT = list_tables(dataset, workspace)
70
64
  dfC = fabric.list_columns(dataset=dataset, workspace=workspace)
@@ -46,8 +46,7 @@ def direct_lake_schema_sync(
46
46
  import Microsoft.AnalysisServices.Tabular as TOM
47
47
  import System
48
48
 
49
- if workspace is None:
50
- workspace = fabric.resolve_workspace_name()
49
+ workspace = fabric.resolve_workspace_name(workspace)
51
50
 
52
51
  if lakehouse_workspace is None:
53
52
  lakehouse_workspace = workspace
@@ -62,10 +61,7 @@ def direct_lake_schema_sync(
62
61
  dfI_filt = dfI[(dfI["Id"] == sqlEndpointId)]
63
62
 
64
63
  if len(dfI_filt) == 0:
65
- print(
66
- f"{icons.red_dot} The SQL Endpoint in the '{dataset}' semantic model in the '{workspace} workspace does not point to the '{lakehouse}' lakehouse in the '{lakehouse_workspace}' workspace as specified."
67
- )
68
- return
64
+ raise ValueError(f"{icons.red_dot} The SQL Endpoint in the '{dataset}' semantic model in the '{workspace} workspace does not point to the '{lakehouse}' lakehouse in the '{lakehouse_workspace}' workspace as specified.")
69
65
 
70
66
  dfP = fabric.list_partitions(dataset=dataset, workspace=workspace)
71
67
  dfP_filt = dfP[dfP["Source Type"] == "Entity"]
@@ -23,17 +23,13 @@ def check_fallback_reason(dataset: str, workspace: Optional[str] = None):
23
23
  The tables in the semantic model and their fallback reason.
24
24
  """
25
25
 
26
- if workspace is None:
27
- workspace_id = fabric.get_workspace_id()
28
- workspace = fabric.resolve_workspace_name(workspace_id)
26
+ workspace = fabric.resolve_workspace_name(workspace)
29
27
 
30
28
  dfP = fabric.list_partitions(dataset=dataset, workspace=workspace)
31
29
  dfP_filt = dfP[dfP["Mode"] == "DirectLake"]
32
30
 
33
31
  if len(dfP_filt) == 0:
34
- print(
35
- f"{icons.yellow_dot} The '{dataset}' semantic model is not in Direct Lake. This function is only applicable to Direct Lake semantic models."
36
- )
32
+ raise ValueError(f"{icons.red_dot} The '{dataset}' semantic model is not in Direct Lake. This function is only applicable to Direct Lake semantic models.")
37
33
  else:
38
34
  df = fabric.evaluate_dax(
39
35
  dataset=dataset,
@@ -1,9 +1,6 @@
1
1
  import sempy
2
2
  import sempy.fabric as fabric
3
- from sempy_labs._helper_functions import (
4
- resolve_lakehouse_name,
5
- resolve_workspace_name_and_id,
6
- )
3
+ from sempy_labs._helper_functions import resolve_lakehouse_name
7
4
  from sempy_labs._list_functions import list_lakehouses
8
5
  from typing import Optional
9
6
  import sempy_labs._icons as icons
@@ -30,7 +27,7 @@ def get_shared_expression(
30
27
  Shows the expression which can be used to connect a Direct Lake semantic model to its SQL Endpoint.
31
28
  """
32
29
 
33
- (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
30
+ workspace = fabric.resolve_workspace_name(workspace)
34
31
  if lakehouse is None:
35
32
  lakehouse_id = fabric.get_lakehouse_id()
36
33
  lakehouse = resolve_lakehouse_name(lakehouse_id)
@@ -43,10 +40,7 @@ def get_shared_expression(
43
40
  provStatus = lakeDetail["SQL Endpoint Provisioning Status"].iloc[0]
44
41
 
45
42
  if provStatus == "InProgress":
46
- print(
47
- f"{icons.red_dot} The SQL Endpoint for the '{lakehouse}' lakehouse within the '{workspace}' workspace has not yet been provisioned. Please wait until it has been provisioned."
48
- )
49
- return
43
+ raise ValueError(f"{icons.red_dot} The SQL Endpoint for the '{lakehouse}' lakehouse within the '{workspace}' workspace has not yet been provisioned. Please wait until it has been provisioned.")
50
44
 
51
45
  sh = (
52
46
  'let\n\tdatabase = Sql.Database("'
@@ -4,7 +4,7 @@ import pandas as pd
4
4
  from typing import List, Optional, Union
5
5
 
6
6
 
7
- def get_direct_lake_guardrails():
7
+ def get_direct_lake_guardrails() -> pd.DataFrame:
8
8
  """
9
9
  Shows the guardrails for when Direct Lake semantic models will fallback to Direct Query based on Microsoft's `online documentation <https://learn.microsoft.com/power-bi/enterprise/directlake-overview>`_.
10
10
 
@@ -44,9 +44,7 @@ def get_sku_size(workspace: Optional[str] = None):
44
44
  The SKU size for a workspace.
45
45
  """
46
46
 
47
- if workspace is None:
48
- workspace_id = fabric.get_workspace_id()
49
- workspace = fabric.resolve_workspace_name(workspace_id)
47
+ workspace = fabric.resolve_workspace_name(workspace)
50
48
 
51
49
  dfC = fabric.list_capacities()
52
50
  dfW = fabric.list_workspaces().sort_values(by="Name", ascending=True)
@@ -62,7 +60,7 @@ def get_sku_size(workspace: Optional[str] = None):
62
60
  return sku_value
63
61
 
64
62
 
65
- def get_directlake_guardrails_for_sku(sku_size: str):
63
+ def get_directlake_guardrails_for_sku(sku_size: str) -> pd.DataFrame:
66
64
  """
67
65
  Shows the guardrails for Direct Lake based on the SKU used by your workspace's capacity.
68
66
  * Use the result of the 'get_sku_size' function as an input for this function's sku_size parameter.*
@@ -8,7 +8,7 @@ from sempy._utils._log import log
8
8
  import sempy_labs._icons as icons
9
9
 
10
10
  @log
11
- def list_direct_lake_model_calc_tables(dataset: str, workspace: Optional[str] = None):
11
+ def list_direct_lake_model_calc_tables(dataset: str, workspace: Optional[str] = None) -> pd.DataFrame:
12
12
  """
13
13
  Shows the calculated tables and their respective DAX expression for a Direct Lake model (which has been migrated from import/DirectQuery).
14
14
 
@@ -27,8 +27,7 @@ def list_direct_lake_model_calc_tables(dataset: str, workspace: Optional[str] =
27
27
  A pandas dataframe showing the calculated tables which were migrated to Direct Lake and whose DAX expressions are stored as model annotations.
28
28
  """
29
29
 
30
- if workspace is None:
31
- workspace = fabric.resolve_workspace_name()
30
+ workspace = fabric.resolve_workspace_name(workspace)
32
31
 
33
32
  df = pd.DataFrame(columns=["Table Name", "Source Expression"])
34
33
 
@@ -39,7 +38,7 @@ def list_direct_lake_model_calc_tables(dataset: str, workspace: Optional[str] =
39
38
  is_direct_lake = tom.is_direct_lake()
40
39
 
41
40
  if not is_direct_lake:
42
- print(f"{icons.yellow_dot} The '{dataset}' semantic model is not in Direct Lake mode.")
41
+ raise ValueError(f"{icons.red_dot} The '{dataset}' semantic model is not in Direct Lake mode.")
43
42
  else:
44
43
  dfA = list_annotations(dataset, workspace)
45
44
  dfT = list_tables(dataset, workspace)
@@ -30,8 +30,7 @@ def show_unsupported_direct_lake_objects(
30
30
 
31
31
  pd.options.mode.chained_assignment = None
32
32
 
33
- if workspace is None:
34
- workspace = fabric.resolve_workspace_name()
33
+ workspace = fabric.resolve_workspace_name(workspace)
35
34
 
36
35
  dfT = list_tables(dataset, workspace)
37
36
  dfC = fabric.list_columns(dataset=dataset, workspace=workspace)
@@ -40,7 +40,7 @@ def update_direct_lake_model_lakehouse_connection(
40
40
 
41
41
  """
42
42
 
43
- (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
43
+ workspace = fabric.resolve_workspace_name(workspace)
44
44
 
45
45
  if lakehouse_workspace is None:
46
46
  lakehouse_workspace = workspace
@@ -54,17 +54,13 @@ def update_direct_lake_model_lakehouse_connection(
54
54
  dfI_filt = dfI[(dfI["Display Name"] == lakehouse)]
55
55
 
56
56
  if len(dfI_filt) == 0:
57
- print(
58
- f"{icons.red_dot} The '{lakehouse}' lakehouse does not exist within the '{lakehouse_workspace}' workspace. Therefore it cannot be used to support the '{dataset}' semantic model within the '{workspace}' workspace."
59
- )
57
+ raise ValueError(f"{icons.red_dot} The '{lakehouse}' lakehouse does not exist within the '{lakehouse_workspace}' workspace. Therefore it cannot be used to support the '{dataset}' semantic model within the '{workspace}' workspace.")
60
58
 
61
59
  dfP = fabric.list_partitions(dataset=dataset, workspace=workspace)
62
60
  dfP_filt = dfP[dfP["Mode"] == "DirectLake"]
63
61
 
64
62
  if len(dfP_filt) == 0:
65
- print(
66
- f"{icons.yellow_dot} The '{dataset}' semantic model is not in Direct Lake. This function is only applicable to Direct Lake semantic models."
67
- )
63
+ raise ValueError(f"{icons.red_dot} The '{dataset}' semantic model is not in Direct Lake. This function is only applicable to Direct Lake semantic models.")
68
64
  else:
69
65
  with connect_semantic_model(
70
66
  dataset=dataset, readonly=False, workspace=workspace