semantic-link-labs 0.4.1__py3-none-any.whl → 0.4.2__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 → semantic_link_labs-0.4.2.dist-info}/METADATA +1 -1
  2. semantic_link_labs-0.4.2.dist-info/RECORD +53 -0
  3. sempy_labs/__init__.py +25 -25
  4. sempy_labs/_ai.py +28 -27
  5. sempy_labs/_clear_cache.py +2 -1
  6. sempy_labs/_dax.py +5 -9
  7. sempy_labs/_generate_semantic_model.py +7 -8
  8. sempy_labs/_helper_functions.py +17 -13
  9. sempy_labs/_icons.py +5 -0
  10. sempy_labs/_list_functions.py +273 -17
  11. sempy_labs/_model_auto_build.py +1 -1
  12. sempy_labs/_model_bpa.py +37 -37
  13. sempy_labs/_model_dependencies.py +11 -12
  14. sempy_labs/_one_lake_integration.py +15 -22
  15. sempy_labs/_query_scale_out.py +1 -1
  16. sempy_labs/_refresh_semantic_model.py +4 -4
  17. sempy_labs/_translations.py +5 -5
  18. sempy_labs/_vertipaq.py +11 -11
  19. sempy_labs/directlake/_directlake_schema_compare.py +11 -9
  20. sempy_labs/directlake/_directlake_schema_sync.py +36 -37
  21. sempy_labs/directlake/_fallback.py +3 -3
  22. sempy_labs/directlake/_get_directlake_lakehouse.py +3 -4
  23. sempy_labs/directlake/_get_shared_expression.py +3 -3
  24. sempy_labs/directlake/_guardrails.py +3 -3
  25. sempy_labs/directlake/_list_directlake_model_calc_tables.py +28 -25
  26. sempy_labs/directlake/_show_unsupported_directlake_objects.py +4 -4
  27. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +10 -11
  28. sempy_labs/directlake/_update_directlake_partition_entity.py +25 -9
  29. sempy_labs/directlake/_warm_cache.py +5 -7
  30. sempy_labs/lakehouse/__init__.py +0 -2
  31. sempy_labs/lakehouse/_get_lakehouse_columns.py +3 -2
  32. sempy_labs/lakehouse/_get_lakehouse_tables.py +10 -7
  33. sempy_labs/lakehouse/_lakehouse.py +6 -5
  34. sempy_labs/lakehouse/_shortcuts.py +8 -106
  35. sempy_labs/migration/__init__.py +4 -2
  36. sempy_labs/migration/_create_pqt_file.py +2 -2
  37. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +7 -7
  38. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +4 -4
  39. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +5 -6
  40. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +6 -6
  41. sempy_labs/migration/_migration_validation.py +1 -164
  42. sempy_labs/migration/_refresh_calc_tables.py +3 -5
  43. sempy_labs/report/__init__.py +2 -2
  44. sempy_labs/report/_generate_report.py +14 -15
  45. sempy_labs/report/_report_functions.py +11 -10
  46. sempy_labs/report/_report_rebind.py +6 -7
  47. sempy_labs/tom/__init__.py +6 -0
  48. sempy_labs/{_tom.py → tom/_model.py} +166 -187
  49. semantic_link_labs-0.4.1.dist-info/RECORD +0 -52
  50. {semantic_link_labs-0.4.1.dist-info → semantic_link_labs-0.4.2.dist-info}/LICENSE +0 -0
  51. {semantic_link_labs-0.4.1.dist-info → semantic_link_labs-0.4.2.dist-info}/WHEEL +0 -0
  52. {semantic_link_labs-0.4.1.dist-info → semantic_link_labs-0.4.2.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,7 @@ from sempy_labs._list_functions import list_relationships
8
8
  from sempy_labs._refresh_semantic_model import refresh_semantic_model
9
9
  from sempy_labs.directlake._fallback import check_fallback_reason
10
10
  from contextlib import contextmanager
11
- from typing import List, Optional, Union, TYPE_CHECKING
11
+ from typing import List, Iterator, Optional, Union, TYPE_CHECKING
12
12
  from sempy._utils._log import log
13
13
  import sempy_labs._icons as icons
14
14
 
@@ -17,32 +17,28 @@ if TYPE_CHECKING:
17
17
  import Microsoft.AnalysisServices.Tabular as TOM
18
18
 
19
19
 
20
- checked = "\u2611"
21
- unchecked = "\u2610"
22
- start_bold = "\033[1m"
23
- end_bold = "\033[0m"
24
-
25
-
26
20
  class TOMWrapper:
27
21
  """
28
- Convenience wrapper around the TOM object model for a semantic model. Always use connect_semantic_model function to make sure the TOM object is initialized correctly.
22
+ Convenience wrapper around the TOM object model for a semantic model. Always use the connect_semantic_model function to make sure the TOM object is initialized correctly.
23
+
24
+ `XMLA read/write endpoints <https://learn.microsoft.com/power-bi/enterprise/service-premium-connect-tools#to-enable-read-write-for-a-premium-capacity>`_ must be enabled if setting the readonly parameter to False.
29
25
  """
30
26
 
31
- dataset: str
32
- workspace: str
33
- readonly: bool
34
- tables_added: List[str]
27
+ _dataset: str
28
+ _workspace: str
29
+ _readonly: bool
30
+ _tables_added: List[str]
35
31
 
36
32
  def __init__(self, dataset, workspace, readonly):
37
- self.dataset = dataset
38
- self.workspace = workspace
39
- self.readonly = readonly
40
- self.tables_added = []
33
+ self._dataset = dataset
34
+ self._workspace = workspace
35
+ self._readonly = readonly
36
+ self._tables_added = []
41
37
 
42
- self.tom_server = fabric.create_tom_server(
38
+ self._tom_server = fabric.create_tom_server(
43
39
  readonly=readonly, workspace=workspace
44
40
  )
45
- self.model = self.tom_server.Databases.GetByName(dataset).Model
41
+ self.model = self._tom_server.Databases.GetByName(dataset).Model
46
42
 
47
43
  def all_columns(self):
48
44
  """
@@ -181,10 +177,10 @@ class TOMWrapper:
181
177
  All levels within the semantic model.
182
178
  """
183
179
 
184
- for t in self.model.Tables:
185
- for h in t.Hierarchies:
186
- for l in h.Levels:
187
- yield l
180
+ for table in self.model.Tables:
181
+ for hierarchy in table.Hierarchies:
182
+ for level in hierarchy.Levels:
183
+ yield level
188
184
 
189
185
  def all_calculation_items(self):
190
186
  """
@@ -459,7 +455,7 @@ class TOMWrapper:
459
455
  Marks the column as the primary key of the table.
460
456
  summarize_by : str, default=None
461
457
  Sets the value for the Summarize By property of the column.
462
- Defaults to None resolves to 'Default'.
458
+ Defaults to None which resolves to 'Default'.
463
459
  """
464
460
  import Microsoft.AnalysisServices.Tabular as TOM
465
461
  import System
@@ -504,7 +500,7 @@ class TOMWrapper:
504
500
  description: Optional[str] = None,
505
501
  ):
506
502
  """
507
- Adds a calculation item to a calculation group within a semantic model.
503
+ Adds a `calculation item <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.calculationitem?view=analysisservices-dotnet>`_ to a `calculation group <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.calculationgroup?view=analysisservices-dotnet>`_ within a semantic model.
508
504
 
509
505
  Parameters
510
506
  ----------
@@ -642,7 +638,7 @@ class TOMWrapper:
642
638
  hierarchy_hidden: Optional[bool] = False,
643
639
  ):
644
640
  """
645
- Adds a hierarchy to a table within a semantic model.
641
+ Adds a `hierarchy <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.hierarchy?view=analysisservices-dotnet>`_ to a table within a semantic model.
646
642
 
647
643
  Parameters
648
644
  ----------
@@ -663,11 +659,11 @@ class TOMWrapper:
663
659
 
664
660
  if isinstance(columns, str):
665
661
  print(
666
- f"The 'levels' parameter must be a list. For example: ['Continent', 'Country', 'City']"
662
+ f"{icons.red_dot} The 'levels' parameter must be a list. For example: ['Continent', 'Country', 'City']"
667
663
  )
668
664
  return
669
665
  if len(columns) == 1:
670
- print(f"There must be at least 2 levels in order to create a hierarchy.")
666
+ print(f"{icons.red_dot} There must be at least 2 levels in order to create a hierarchy.")
671
667
  return
672
668
 
673
669
  if levels is None:
@@ -675,7 +671,7 @@ class TOMWrapper:
675
671
 
676
672
  if len(columns) != len(levels):
677
673
  print(
678
- f"If specifying level names, you must specify a level for each column."
674
+ f"{icons.red_dot} If specifying level names, you must specify a level for each column."
679
675
  )
680
676
  return
681
677
 
@@ -707,7 +703,7 @@ class TOMWrapper:
707
703
  rely_on_referential_integrity: Optional[bool] = False,
708
704
  ):
709
705
  """
710
- Adds a relationship to a semantic model.
706
+ Adds a `relationship <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.singlecolumnrelationship?view=analysisservices-dotnet>`_ to a semantic model.
711
707
 
712
708
  Parameters
713
709
  ----------
@@ -779,7 +775,7 @@ class TOMWrapper:
779
775
  hidden: Optional[bool] = False,
780
776
  ):
781
777
  """
782
- Adds a calculation group to a semantic model.
778
+ Adds a `calculation group <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.calculationgroup?view=analysisservices-dotnet>`_ to a semantic model.
783
779
 
784
780
  Parameters
785
781
  ----------
@@ -832,7 +828,7 @@ class TOMWrapper:
832
828
  self, name: str, expression: str, description: Optional[str] = None
833
829
  ):
834
830
  """
835
- Adds an expression to a semantic model.
831
+ Adds an `expression <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.namedexpression?view=analysisservices-dotnet>`_ to a semantic model.
836
832
 
837
833
  Parameters
838
834
  ----------
@@ -856,7 +852,7 @@ class TOMWrapper:
856
852
 
857
853
  def add_translation(self, language: str):
858
854
  """
859
- Adds a translation language (culture) to a semantic model.
855
+ Adds a `translation language <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.culture?view=analysisservices-dotnet>`_ (culture) to a semantic model.
860
856
 
861
857
  Parameters
862
858
  ----------
@@ -875,7 +871,7 @@ class TOMWrapper:
875
871
 
876
872
  def add_perspective(self, perspective_name: str):
877
873
  """
878
- Adds a perspective to a semantic model.
874
+ Adds a `perspective <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.perspective?view=analysisservices-dotnet>`_ to a semantic model.
879
875
 
880
876
  Parameters
881
877
  ----------
@@ -910,18 +906,22 @@ class TOMWrapper:
910
906
  mode : str, default=None
911
907
  The query mode for the partition.
912
908
  Defaults to None which resolves to 'Import'.
909
+ `Valid mode values <https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.tabular.modetype?view=analysisservices-dotnet>`_
913
910
  description : str, default=None
914
911
  A description for the partition.
915
912
  """
916
913
  import Microsoft.AnalysisServices.Tabular as TOM
917
914
  import System
918
915
 
919
- mode = (
920
- mode.title()
921
- .replace("query", "Query")
922
- .replace(" ", "")
923
- .replace("lake", "Lake")
924
- )
916
+ if mode is None:
917
+ mode = "Default"
918
+ else:
919
+ mode = (
920
+ mode.title()
921
+ .replace("query", "Query")
922
+ .replace(" ", "")
923
+ .replace("lake", "Lake")
924
+ )
925
925
 
926
926
  mp = TOM.MPartitionSource()
927
927
  mp.Expression = expression
@@ -930,8 +930,6 @@ class TOMWrapper:
930
930
  p.Source = mp
931
931
  if description is not None:
932
932
  p.Description = description
933
- if mode is None:
934
- mode = "Default"
935
933
  p.Mode = System.Enum.Parse(TOM.ModeType, mode)
936
934
 
937
935
  self.model.Tables[table_name].Partitions.Add(p)
@@ -966,7 +964,7 @@ class TOMWrapper:
966
964
  if expression is None:
967
965
  ep.ExpressionSource = self.model.Expressions["DatabaseQuery"]
968
966
  else:
969
- ep.ExpressionSource = expression
967
+ ep.ExpressionSource = self.model.Expressions[expression]
970
968
  p = TOM.Partition()
971
969
  p.Name = table_name
972
970
  p.Source = ep
@@ -985,7 +983,7 @@ class TOMWrapper:
985
983
  base_column: Optional[str] = None,
986
984
  ):
987
985
  """
988
- Sets the 'alternate of' property on a column.
986
+ Sets the `alternate of <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.alternateof?view=analysisservices-dotnet>`_ property on a column.
989
987
 
990
988
  Parameters
991
989
  ----------
@@ -1006,7 +1004,7 @@ class TOMWrapper:
1006
1004
 
1007
1005
  if base_column is not None and base_table is None:
1008
1006
  print(
1009
- f"ERROR: If you specify the base table you must also specify the base column"
1007
+ f"{icons.red_dot} If you specify the base table you must also specify the base column"
1010
1008
  )
1011
1009
 
1012
1010
  summarization_type = (
@@ -1018,7 +1016,7 @@ class TOMWrapper:
1018
1016
  summarizationTypes = ["Sum", "GroupBy", "Count", "Min", "Max"]
1019
1017
  if summarization_type not in summarizationTypes:
1020
1018
  print(
1021
- f"The 'summarization_type' parameter must be one of the following valuse: {summarizationTypes}."
1019
+ f"{icons.red_dot} The 'summarization_type' parameter must be one of the following valuse: {summarizationTypes}."
1022
1020
  )
1023
1021
  return
1024
1022
 
@@ -1039,7 +1037,7 @@ class TOMWrapper:
1039
1037
 
1040
1038
  def remove_alternate_of(self, table_name: str, column_name: str):
1041
1039
  """
1042
- Removes the 'alternate of' property on a column.
1040
+ Removes the `alternate of <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.alternateof?view=analysisservices-dotnet>`_ property on a column.
1043
1041
 
1044
1042
  Parameters
1045
1043
  ----------
@@ -1059,7 +1057,7 @@ class TOMWrapper:
1059
1057
  self, object
1060
1058
  ) -> "Microsoft.AnalysisServices.Tabular.Annotation":
1061
1059
  """
1062
- Shows all annotations for a given object within a semantic model.
1060
+ Shows all `annotations <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.annotation?view=analysisservices-dotnet>`_ for a given object within a semantic model.
1063
1061
 
1064
1062
  Parameters
1065
1063
  ----------
@@ -1081,7 +1079,7 @@ class TOMWrapper:
1081
1079
 
1082
1080
  def set_annotation(self, object, name: str, value: str):
1083
1081
  """
1084
- Sets an annotation on an object within the semantic model.
1082
+ Sets an `annotation <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.annotation?view=analysisservices-dotnet>`_ on an object within the semantic model.
1085
1083
 
1086
1084
  Parameters
1087
1085
  ----------
@@ -1105,7 +1103,7 @@ class TOMWrapper:
1105
1103
 
1106
1104
  def get_annotation_value(self, object, name: str):
1107
1105
  """
1108
- Obtains the annotation value for a given annotation on an object within the semantic model.
1106
+ Obtains the `annotation <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.annotation?view=analysisservices-dotnet>`_ value for a given annotation on an object within the semantic model.
1109
1107
 
1110
1108
  Parameters
1111
1109
  ----------
@@ -1124,7 +1122,7 @@ class TOMWrapper:
1124
1122
 
1125
1123
  def remove_annotation(self, object, name: str):
1126
1124
  """
1127
- Removes an annotation on an object within the semantic model.
1125
+ Removes an `annotation <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.annotation?view=analysisservices-dotnet>`_ on an object within the semantic model.
1128
1126
 
1129
1127
  Parameters
1130
1128
  ----------
@@ -1138,7 +1136,7 @@ class TOMWrapper:
1138
1136
 
1139
1137
  def clear_annotations(self, object):
1140
1138
  """
1141
- Removes all annotations on an object within the semantic model.
1139
+ Removes all `annotations <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.annotation?view=analysisservices-dotnet>`_ on an object within the semantic model.
1142
1140
 
1143
1141
  Parameters
1144
1142
  ----------
@@ -1152,7 +1150,7 @@ class TOMWrapper:
1152
1150
  self, object
1153
1151
  ) -> "Microsoft.AnalysisServices.Tabular.ExtendedProperty":
1154
1152
  """
1155
- Retrieves all extended properties on an object within the semantic model.
1153
+ Retrieves all `extended properties <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.extendedproperty?view=analysisservices-dotnet>`_ on an object within the semantic model.
1156
1154
 
1157
1155
  Parameters
1158
1156
  ----------
@@ -1172,7 +1170,7 @@ class TOMWrapper:
1172
1170
  self, object, extended_property_type: str, name: str, value: str
1173
1171
  ):
1174
1172
  """
1175
- Sets an extended property on an object within the semantic model.
1173
+ Sets an `extended property <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.extendedproperty?view=analysisservices-dotnet>`_ on an object within the semantic model.
1176
1174
 
1177
1175
  Parameters
1178
1176
  ----------
@@ -1205,7 +1203,7 @@ class TOMWrapper:
1205
1203
 
1206
1204
  def get_extended_property_value(self, object, name: str):
1207
1205
  """
1208
- Retrieves the value of an extended property for an object within the semantic model.
1206
+ Retrieves the value of an `extended property <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.extendedproperty?view=analysisservices-dotnet>`_ for an object within the semantic model.
1209
1207
 
1210
1208
  Parameters
1211
1209
  ----------
@@ -1224,7 +1222,7 @@ class TOMWrapper:
1224
1222
 
1225
1223
  def remove_extended_property(self, object, name: str):
1226
1224
  """
1227
- Removes an extended property on an object within the semantic model.
1225
+ Removes an `extended property <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.extendedproperty?view=analysisservices-dotnet>`_ on an object within the semantic model.
1228
1226
 
1229
1227
  Parameters
1230
1228
  ----------
@@ -1238,7 +1236,7 @@ class TOMWrapper:
1238
1236
 
1239
1237
  def clear_extended_properties(self, object):
1240
1238
  """
1241
- Removes all extended properties on an object within the semantic model.
1239
+ Removes all `extended properties <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.extendedproperty?view=analysisservices-dotnet>`_ on an object within the semantic model.
1242
1240
 
1243
1241
  Parameters
1244
1242
  ----------
@@ -1254,7 +1252,7 @@ class TOMWrapper:
1254
1252
  perspective_name: str,
1255
1253
  ):
1256
1254
  """
1257
- Indicates whether an object is contained within a given perspective.
1255
+ Indicates whether an object is contained within a given `perspective <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.perspective?view=analysisservices-dotnet>`_.
1258
1256
 
1259
1257
  Parameters
1260
1258
  ----------
@@ -1280,7 +1278,7 @@ class TOMWrapper:
1280
1278
 
1281
1279
  if objectType not in validObjects:
1282
1280
  print(
1283
- f"Only the following object types are valid for perspectives: {validObjects}."
1281
+ f"{icons.red_dot} Only the following object types are valid for perspectives: {validObjects}."
1284
1282
  )
1285
1283
  return
1286
1284
 
@@ -1313,7 +1311,7 @@ class TOMWrapper:
1313
1311
  perspective_name: str,
1314
1312
  ):
1315
1313
  """
1316
- Adds an object to a perspective.
1314
+ Adds an object to a `perspective <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.perspective?view=analysisservices-dotnet>`_.
1317
1315
 
1318
1316
  Parameters
1319
1317
  ----------
@@ -1334,13 +1332,13 @@ class TOMWrapper:
1334
1332
 
1335
1333
  if objectType not in validObjects:
1336
1334
  print(
1337
- f"Only the following object types are valid for perspectives: {validObjects}."
1335
+ f"{icons.red_dot} Only the following object types are valid for perspectives: {validObjects}."
1338
1336
  )
1339
1337
  return
1340
1338
  try:
1341
1339
  object.Model.Perspectives[perspective_name]
1342
1340
  except:
1343
- print(f"The '{perspective_name}' perspective does not exist.")
1341
+ print(f"{icons.red_dot} The '{perspective_name}' perspective does not exist.")
1344
1342
  return
1345
1343
 
1346
1344
  # try:
@@ -1375,7 +1373,7 @@ class TOMWrapper:
1375
1373
  perspective_name: str,
1376
1374
  ):
1377
1375
  """
1378
- Removes an object from a perspective.
1376
+ Removes an object from a `perspective <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.perspective?view=analysisservices-dotnet>`_.
1379
1377
 
1380
1378
  Parameters
1381
1379
  ----------
@@ -1396,13 +1394,13 @@ class TOMWrapper:
1396
1394
 
1397
1395
  if objectType not in validObjects:
1398
1396
  print(
1399
- f"Only the following object types are valid for perspectives: {validObjects}."
1397
+ f"{icons.red_dot} Only the following object types are valid for perspectives: {validObjects}."
1400
1398
  )
1401
1399
  return
1402
1400
  try:
1403
1401
  object.Model.Perspectives[perspective_name]
1404
1402
  except:
1405
- print(f"The '{perspective_name}' perspective does not exist.")
1403
+ print(f"{icons.red_dot} The '{perspective_name}' perspective does not exist.")
1406
1404
  return
1407
1405
 
1408
1406
  # try:
@@ -1449,7 +1447,7 @@ class TOMWrapper:
1449
1447
  value: str,
1450
1448
  ):
1451
1449
  """
1452
- Sets a translation value for an object's property.
1450
+ Sets a `translation <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.culture?view=analysisservices-dotnet>`_ value for an object's property.
1453
1451
 
1454
1452
  Parameters
1455
1453
  ----------
@@ -1476,7 +1474,7 @@ class TOMWrapper:
1476
1474
  ] # , 'Level'
1477
1475
 
1478
1476
  if object.ObjectType not in validObjects:
1479
- print(f"Translations can only be set to {validObjects}.")
1477
+ print(f"{icons.red_dot} Translations can only be set to {validObjects}.")
1480
1478
  return
1481
1479
 
1482
1480
  mapping = {
@@ -1491,7 +1489,7 @@ class TOMWrapper:
1491
1489
  object.Model.Cultures[language]
1492
1490
  except:
1493
1491
  print(
1494
- f"The '{language}' translation language does not exist in the semantic model."
1492
+ f"{icons.red_dot} The '{language}' translation language does not exist in the semantic model."
1495
1493
  )
1496
1494
  return
1497
1495
 
@@ -1505,7 +1503,7 @@ class TOMWrapper:
1505
1503
  language: str,
1506
1504
  ):
1507
1505
  """
1508
- Removes an object's translation value.
1506
+ Removes an object's `translation <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.culture?view=analysisservices-dotnet>`_ value.
1509
1507
 
1510
1508
  Parameters
1511
1509
  ----------
@@ -1579,7 +1577,7 @@ class TOMWrapper:
1579
1577
 
1580
1578
  def used_in_relationships(self, object: Union["TOM.Table", "TOM.Column"]):
1581
1579
  """
1582
- Shows all relationships in which a table/column is used.
1580
+ Shows all `relationships <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.singlecolumnrelationship?view=analysisservices-dotnet>`_ in which a table/column is used.
1583
1581
 
1584
1582
  Parameters
1585
1583
  ----------
@@ -1612,7 +1610,7 @@ class TOMWrapper:
1612
1610
 
1613
1611
  def used_in_levels(self, column: "TOM.Column"):
1614
1612
  """
1615
- Shows all levels in which a column is used.
1613
+ Shows all `levels <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.level?view=analysisservices-dotnet>`_ in which a column is used.
1616
1614
 
1617
1615
  Parameters
1618
1616
  ----------
@@ -1629,16 +1627,16 @@ class TOMWrapper:
1629
1627
  objType = column.ObjectType
1630
1628
 
1631
1629
  if objType == TOM.ObjectType.Column:
1632
- for l in self.all_levels():
1630
+ for level in self.all_levels():
1633
1631
  if (
1634
- l.Parent.Table.Name == column.Parent.Name
1635
- and l.Column.Name == column.Name
1632
+ level.Parent.Table.Name == column.Parent.Name
1633
+ and level.Column.Name == column.Name
1636
1634
  ):
1637
- yield l
1635
+ yield level
1638
1636
 
1639
1637
  def used_in_hierarchies(self, column: "TOM.Column"):
1640
1638
  """
1641
- Shows all hierarchies in which a column is used.
1639
+ Shows all `hierarchies <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.hierarchy?view=analysisservices-dotnet>`_ in which a column is used.
1642
1640
 
1643
1641
  Parameters
1644
1642
  ----------
@@ -1691,7 +1689,7 @@ class TOMWrapper:
1691
1689
  dependencies: pd.DataFrame,
1692
1690
  ):
1693
1691
  """
1694
- Identifies the filter expressions which reference a given object.
1692
+ Identifies the row level security `filter expressions <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.tablepermission.filterexpression?view=analysisservices-dotnet#microsoft-analysisservices-tabular-tablepermission-filterexpression>`_ which reference a given object.
1695
1693
 
1696
1694
  Parameters
1697
1695
  ----------
@@ -1855,7 +1853,7 @@ class TOMWrapper:
1855
1853
 
1856
1854
  def hybrid_tables(self):
1857
1855
  """
1858
- Outputs the hybrid tables within a semantic model.
1856
+ Outputs the `hybrid tables <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_ within a semantic model.
1859
1857
 
1860
1858
  Parameters
1861
1859
  ----------
@@ -1874,7 +1872,7 @@ class TOMWrapper:
1874
1872
 
1875
1873
  def date_tables(self):
1876
1874
  """
1877
- Outputs the tables which are marked as date tables within a semantic model.
1875
+ Outputs the tables which are marked as `date tables <https://learn.microsoft.com/power-bi/transform-model/desktop-date-tables>`_ within a semantic model.
1878
1876
 
1879
1877
  Parameters
1880
1878
  ----------
@@ -1895,7 +1893,7 @@ class TOMWrapper:
1895
1893
 
1896
1894
  def is_hybrid_table(self, table_name: str):
1897
1895
  """
1898
- Identifies if a table is a hybrid table.
1896
+ Identifies if a table is a `hybrid table <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_.
1899
1897
 
1900
1898
  Parameters
1901
1899
  ----------
@@ -1925,7 +1923,7 @@ class TOMWrapper:
1925
1923
 
1926
1924
  def is_date_table(self, table_name: str):
1927
1925
  """
1928
- Identifies if a table is marked as a date table.
1926
+ Identifies if a table is marked as a `date tables <https://learn.microsoft.com/power-bi/transform-model/desktop-date-tables>`_.
1929
1927
 
1930
1928
  Parameters
1931
1929
  ----------
@@ -1939,18 +1937,11 @@ class TOMWrapper:
1939
1937
  """
1940
1938
  import Microsoft.AnalysisServices.Tabular as TOM
1941
1939
 
1942
- isDateTable = False
1943
- t = self.model.Tables[table_name]
1944
-
1945
- if t.DataCategory == "Time":
1946
- if any(c.IsKey and c.DataType == TOM.DataType.DateTime for c in t.Columns):
1947
- isDateTable = True
1948
-
1949
- return isDateTable
1940
+ return any(c.IsKey and c.DataType == TOM.DataType.DateTime for c in self.all_columns() if c.Parent.Name == table_name and c.Parent.DataCategory == 'Time')
1950
1941
 
1951
1942
  def mark_as_date_table(self, table_name: str, column_name: str):
1952
1943
  """
1953
- Marks a table as a date table.
1944
+ Marks a table as a `date table <https://learn.microsoft.com/power-bi/transform-model/desktop-date-tables>`_.
1954
1945
 
1955
1946
  Parameters
1956
1947
  ----------
@@ -1983,7 +1974,7 @@ class TOMWrapper:
1983
1974
  )
1984
1975
  """
1985
1976
  df = fabric.evaluate_dax(
1986
- dataset=self.dataset, workspace=self.workspace, dax_string=daxQuery
1977
+ dataset=self._dataset, workspace=self._workspace, dax_string=daxQuery
1987
1978
  )
1988
1979
  value = df["1"].iloc[0]
1989
1980
  if value != "1":
@@ -2001,7 +1992,7 @@ class TOMWrapper:
2001
1992
 
2002
1993
  def has_aggs(self):
2003
1994
  """
2004
- Identifies if a semantic model has any aggregations.
1995
+ Identifies if a semantic model has any `aggregations <https://learn.microsoft.com/power-bi/transform-model/aggregations-advanced>`_.
2005
1996
 
2006
1997
  Parameters
2007
1998
  ----------
@@ -2012,17 +2003,11 @@ class TOMWrapper:
2012
2003
  Indicates if the semantic model has any aggregations.
2013
2004
  """
2014
2005
 
2015
- hasAggs = False
2016
-
2017
- for c in self.all_columns():
2018
- if c.AlterateOf is not None:
2019
- hasAggs = True
2020
-
2021
- return hasAggs
2006
+ return any(c.AlternateOf is not None for c in self.all_columns())
2022
2007
 
2023
2008
  def is_agg_table(self, table_name: str):
2024
2009
  """
2025
- Identifies if a table has aggregations.
2010
+ Identifies if a table has `aggregations <https://learn.microsoft.com/power-bi/transform-model/aggregations-advanced>`_.
2026
2011
 
2027
2012
  Parameters
2028
2013
  ----------
@@ -2041,7 +2026,7 @@ class TOMWrapper:
2041
2026
 
2042
2027
  def has_hybrid_table(self):
2043
2028
  """
2044
- Identifies if a semantic model has a hybrid table.
2029
+ Identifies if a semantic model has a `hybrid table <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_.
2045
2030
 
2046
2031
  Parameters
2047
2032
  ----------
@@ -2050,19 +2035,13 @@ class TOMWrapper:
2050
2035
  -------
2051
2036
  bool
2052
2037
  Indicates if the semantic model has a hybrid table.
2053
- """
2054
-
2055
- hasHybridTable = False
2038
+ """
2056
2039
 
2057
- for t in self.model.Tables:
2058
- if self.is_hybrid_table(table_name=t.Name):
2059
- hasHybridTable = True
2060
-
2061
- return hasHybridTable
2040
+ return any(self.is_hybrid_table(table_name=t.Name) for t in self.model.Tables)
2062
2041
 
2063
2042
  def has_date_table(self):
2064
2043
  """
2065
- Identifies if a semantic model has a table marked as a date table.
2044
+ Identifies if a semantic model has a table marked as a `date table <https://learn.microsoft.com/power-bi/transform-model/desktop-date-tables>`_.
2066
2045
 
2067
2046
  Parameters
2068
2047
  ----------
@@ -2073,17 +2052,11 @@ class TOMWrapper:
2073
2052
  Indicates if the semantic model has a table marked as a date table.
2074
2053
  """
2075
2054
 
2076
- hasDateTable = False
2077
-
2078
- for t in self.model.Tables:
2079
- if self.is_date_table(table_name=t.Name):
2080
- hasDateTable = True
2081
-
2082
- return hasDateTable
2055
+ return any(self.is_date_table(table_name=t.Name) for t in self.model.Tables)
2083
2056
 
2084
2057
  def is_direct_lake(self):
2085
2058
  """
2086
- Identifies if a semantic model is in Direct Lake mode.
2059
+ Identifies if a semantic model is in `Direct Lake <https://learn.microsoft.com/fabric/get-started/direct-lake-overview>`_ mode.
2087
2060
 
2088
2061
  Parameters
2089
2062
  ----------
@@ -2093,6 +2066,7 @@ class TOMWrapper:
2093
2066
  bool
2094
2067
  Indicates if the semantic model is in Direct Lake mode.
2095
2068
  """
2069
+ import Microsoft.AnalysisServices.Tabular as TOM
2096
2070
 
2097
2071
  return any(
2098
2072
  p.Mode == TOM.ModeType.DirectLake
@@ -2102,7 +2076,7 @@ class TOMWrapper:
2102
2076
 
2103
2077
  def is_field_parameter(self, table_name: str):
2104
2078
  """
2105
- Identifies if a table is a field parameter.
2079
+ Identifies if a table is a `field parameter <https://learn.microsoft.com/power-bi/create-reports/power-bi-field-parameters>`_.
2106
2080
 
2107
2081
  Parameters
2108
2082
  ----------
@@ -2134,7 +2108,7 @@ class TOMWrapper:
2134
2108
 
2135
2109
  def is_auto_date_table(self, table_name: str):
2136
2110
  """
2137
- Identifies if a table is an auto-date table.
2111
+ Identifies if a table is an `auto date/time table <https://learn.microsoft.com/power-bi/transform-model/desktop-auto-date-time>`_.
2138
2112
 
2139
2113
  Parameters
2140
2114
  ----------
@@ -2174,7 +2148,7 @@ class TOMWrapper:
2174
2148
  status_graphic: Optional[str] = None,
2175
2149
  ):
2176
2150
  """
2177
- Sets the properties to add/update a KPI for a measure.
2151
+ Sets the properties to add/update a `KPI <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.kpi?view=analysisservices-dotnet>`_ for a measure.
2178
2152
 
2179
2153
  Parameters
2180
2154
  ----------
@@ -2203,47 +2177,48 @@ class TOMWrapper:
2203
2177
 
2204
2178
  if measure_name == target:
2205
2179
  print(
2206
- f"The 'target' parameter cannot be the same measure as the 'measure_name' parameter."
2180
+ f"{icons.red_dot} The 'target' parameter cannot be the same measure as the 'measure_name' parameter."
2207
2181
  )
2208
2182
  return
2209
2183
 
2210
2184
  if status_graphic is None:
2211
2185
  status_graphic = "Three Circles Colored"
2212
2186
 
2213
- statusType = ["Linear", "LinearReversed", "Centered", "CenteredReversed"]
2214
- status_type = status_type.title().replace(" ", "")
2215
-
2187
+ valid_status_types = ["Linear", "LinearReversed", "Centered", "CenteredReversed"]
2188
+ status_type = status_type
2216
2189
  if status_type is None:
2217
2190
  status_type = "Linear"
2191
+ else:
2192
+ status_type = status_type.title().replace(" ", "")
2218
2193
 
2219
- if status_type not in statusType:
2194
+ if status_type not in valid_status_types:
2220
2195
  print(
2221
- f"'{status_type}' is an invalid status_type. Please choose from these options: {statusType}."
2196
+ f"{icons.red_dot} '{status_type}' is an invalid status_type. Please choose from these options: {valid_status_types}."
2222
2197
  )
2223
2198
  return
2224
2199
 
2225
2200
  if status_type in ["Linear", "LinearReversed"]:
2226
2201
  if upper_bound is not None or lower_mid_bound is not None:
2227
2202
  print(
2228
- f"The 'upper_mid_bound' and 'lower_mid_bound' parameters are not used in the 'Linear' and 'LinearReversed' status types. Make sure these parameters are set to None."
2203
+ f"{icons.red_dot} The 'upper_mid_bound' and 'lower_mid_bound' parameters are not used in the 'Linear' and 'LinearReversed' status types. Make sure these parameters are set to None."
2229
2204
  )
2230
2205
  return
2231
2206
  elif upper_bound <= lower_bound:
2232
- print(f"The upper_bound must be greater than the lower_bound.")
2207
+ print(f"{icons.red_dot} The upper_bound must be greater than the lower_bound.")
2233
2208
  return
2234
2209
 
2235
2210
  if status_type in ["Centered", "CenteredReversed"]:
2236
2211
  if upper_mid_bound is None or lower_mid_bound is None:
2237
2212
  print(
2238
- f"The 'upper_mid_bound' and 'lower_mid_bound' parameters are necessary in the 'Centered' and 'CenteredReversed' status types."
2213
+ f"{icons.red_dot} The 'upper_mid_bound' and 'lower_mid_bound' parameters are necessary in the 'Centered' and 'CenteredReversed' status types."
2239
2214
  )
2240
2215
  return
2241
2216
  elif upper_bound <= upper_mid_bound:
2242
- print(f"The upper_bound must be greater than the upper_mid_bound.")
2217
+ print(f"{icons.red_dot} The upper_bound must be greater than the upper_mid_bound.")
2243
2218
  elif upper_mid_bound <= lower_mid_bound:
2244
- print(f"The upper_mid_bound must be greater than the lower_mid_bound.")
2219
+ print(f"{icons.red_dot} The upper_mid_bound must be greater than the lower_mid_bound.")
2245
2220
  elif lower_mid_bound <= lower_bound:
2246
- print(f"The lower_mid_bound must be greater than the lower_bound.")
2221
+ print(f"{icons.red_dot} The lower_mid_bound must be greater than the lower_bound.")
2247
2222
 
2248
2223
  try:
2249
2224
  table_name = next(
@@ -2251,7 +2226,7 @@ class TOMWrapper:
2251
2226
  )
2252
2227
  except:
2253
2228
  print(
2254
- f"The '{measure_name}' measure does not exist in the '{self.dataset}' semantic model within the '{self.workspace}'."
2229
+ f"{icons.red_dot} The '{measure_name}' measure does not exist in the '{self._dataset}' semantic model within the '{self._workspace}'."
2255
2230
  )
2256
2231
  return
2257
2232
 
@@ -2277,7 +2252,7 @@ class TOMWrapper:
2277
2252
 
2278
2253
  if status_graphic not in graphics:
2279
2254
  print(
2280
- f"The '{status_graphic}' status graphic is not valid. Please choose from these options: {graphics}."
2255
+ f"{icons.red_dot} The '{status_graphic}' status graphic is not valid. Please choose from these options: {graphics}."
2281
2256
  )
2282
2257
  return
2283
2258
 
@@ -2296,7 +2271,7 @@ class TOMWrapper:
2296
2271
  )
2297
2272
  except:
2298
2273
  print(
2299
- f"The '{target}' measure does not exist in the '{self.dataset}' semantic model within the '{self.workspace}'."
2274
+ f"{icons.red_dot} The '{target}' measure does not exist in the '{self._dataset}' semantic model within the '{self._workspace}'."
2300
2275
  )
2301
2276
 
2302
2277
  if measure_target:
@@ -2328,7 +2303,7 @@ class TOMWrapper:
2328
2303
 
2329
2304
  def set_aggregations(self, table_name: str, agg_table_name: str):
2330
2305
  """
2331
- Sets the aggregations (alternate of) for all the columns in an aggregation table based on a base table.
2306
+ Sets the `aggregations <https://learn.microsoft.com/power-bi/transform-model/aggregations-advanced>`_ (alternate of) for all the columns in an aggregation table based on a base table.
2332
2307
 
2333
2308
  Parameters
2334
2309
  ----------
@@ -2367,7 +2342,7 @@ class TOMWrapper:
2367
2342
  self, table_name: str, column_name: str, value: Optional[bool] = False
2368
2343
  ):
2369
2344
  """
2370
- Sets the IsAvailableInMdx property on a column.
2345
+ Sets the `IsAvailableInMDX <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.column.isavailableinmdx?view=analysisservices-dotnet#microsoft-analysisservices-tabular-column-isavailableinmdx>`_ property on a column.
2371
2346
 
2372
2347
  Parameters
2373
2348
  ----------
@@ -2385,7 +2360,7 @@ class TOMWrapper:
2385
2360
  self, table_name: str, column_name: str, value: Optional[str] = None
2386
2361
  ):
2387
2362
  """
2388
- Sets the SummarizeBy property on a column.
2363
+ Sets the `SummarizeBy <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.column.summarizeby?view=analysisservices-dotnet#microsoft-analysisservices-tabular-column-summarizeby>`_ property on a column.
2389
2364
 
2390
2365
  Parameters
2391
2366
  ----------
@@ -2422,7 +2397,7 @@ class TOMWrapper:
2422
2397
 
2423
2398
  if value not in values:
2424
2399
  print(
2425
- f"'{value}' is not a valid value for the SummarizeBy property. These are the valid values: {values}."
2400
+ f"{icons.red_dot} '{value}' is not a valid value for the SummarizeBy property. These are the valid values: {values}."
2426
2401
  )
2427
2402
  return
2428
2403
 
@@ -2432,7 +2407,7 @@ class TOMWrapper:
2432
2407
 
2433
2408
  def set_direct_lake_behavior(self, direct_lake_behavior: str):
2434
2409
  """
2435
- Sets the Direct Lake Behavior property for a semantic model.
2410
+ Sets the `Direct Lake Behavior <https://learn.microsoft.com/fabric/get-started/direct-lake-overview#fallback-behavior>`_ property for a semantic model.
2436
2411
 
2437
2412
  Parameters
2438
2413
  ----------
@@ -2454,7 +2429,7 @@ class TOMWrapper:
2454
2429
 
2455
2430
  if direct_lake_behavior not in dlValues:
2456
2431
  print(
2457
- f"The 'direct_lake_behavior' parameter must be one of these values: {dlValues}."
2432
+ f"{icons.red_dot} The 'direct_lake_behavior' parameter must be one of these values: {dlValues}."
2458
2433
  )
2459
2434
  return
2460
2435
 
@@ -2539,7 +2514,7 @@ class TOMWrapper:
2539
2514
 
2540
2515
  def add_field_parameter(self, table_name: str, objects: List[str]):
2541
2516
  """
2542
- Adds a table to the semantic model.
2517
+ Adds a `field parameter <https://learn.microsoft.com/power-bi/create-reports/power-bi-field-parameters>`_ to the semantic model.
2543
2518
 
2544
2519
  Parameters
2545
2520
  ----------
@@ -2551,12 +2526,14 @@ class TOMWrapper:
2551
2526
  Measures may be formatted as '[Measure Name]' or 'Measure Name'.
2552
2527
  """
2553
2528
 
2529
+ import Microsoft.AnalysisServices.Tabular as TOM
2530
+
2554
2531
  if isinstance(objects, str):
2555
- print(f"The 'objects' parameter must be a list of columns/measures.")
2532
+ print(f"{icons.red_dot} The 'objects' parameter must be a list of columns/measures.")
2556
2533
  return
2557
2534
  if len(objects) == 1:
2558
2535
  print(
2559
- f"There must be more than one object (column/measure) within the objects parameter."
2536
+ f"{icons.red_dot} There must be more than one object (column/measure) within the objects parameter."
2560
2537
  )
2561
2538
  return
2562
2539
 
@@ -2595,7 +2572,7 @@ class TOMWrapper:
2595
2572
  success = True
2596
2573
  if not success:
2597
2574
  print(
2598
- f"The '{obj}' object was not found in the '{self.dataset}' semantic model."
2575
+ f"{icons.red_dot} The '{obj}' object was not found in the '{self._dataset}' semantic model."
2599
2576
  )
2600
2577
  return
2601
2578
  else:
@@ -2631,7 +2608,6 @@ class TOMWrapper:
2631
2608
  )
2632
2609
 
2633
2610
  self.set_extended_property(
2634
- self=self,
2635
2611
  object=self.model.Tables[table_name].Columns[col2],
2636
2612
  extended_property_type="Json",
2637
2613
  name="ParameterMetadata",
@@ -2649,11 +2625,11 @@ class TOMWrapper:
2649
2625
  ].Columns[col3]
2650
2626
  self.model.Tables[table_name].Columns[table_name].RelatedColumnDetails = rcd
2651
2627
 
2652
- self.tables_added.append(table_name)
2628
+ self._tables_added.append(table_name)
2653
2629
 
2654
2630
  def remove_vertipaq_annotations(self):
2655
2631
  """
2656
- Removes the annotations set using the [set_vertipaq_annotations] function.
2632
+ Removes the annotations set using the set_vertipaq_annotations function.
2657
2633
  """
2658
2634
 
2659
2635
  for t in self.model.Tables:
@@ -2683,10 +2659,10 @@ class TOMWrapper:
2683
2659
  """
2684
2660
 
2685
2661
  dfT = fabric.list_tables(
2686
- dataset=self.dataset, workspace=self.workspace, extended=True
2662
+ dataset=self._dataset, workspace=self._workspace, extended=True
2687
2663
  )
2688
2664
  dfC = fabric.list_columns(
2689
- dataset=self.dataset, workspace=self.workspace, extended=True
2665
+ dataset=self._dataset, workspace=self._workspace, extended=True
2690
2666
  )
2691
2667
  # intList = ['Total Size']#, 'Data Size', 'Dictionary Size', 'Hierarchy Size']
2692
2668
  dfCSum = dfC.groupby(["Table Name"])["Total Size"].sum().reset_index()
@@ -2698,16 +2674,16 @@ class TOMWrapper:
2698
2674
  how="inner",
2699
2675
  )
2700
2676
  dfP = fabric.list_partitions(
2701
- dataset=self.dataset, workspace=self.workspace, extended=True
2677
+ dataset=self._dataset, workspace=self._workspace, extended=True
2702
2678
  )
2703
2679
  dfP["Records per Segment"] = round(
2704
2680
  dfP["Record Count"] / dfP["Segment Count"], 2
2705
2681
  )
2706
2682
  dfH = fabric.list_hierarchies(
2707
- dataset=self.dataset, workspace=self.workspace, extended=True
2683
+ dataset=self._dataset, workspace=self._workspace, extended=True
2708
2684
  )
2709
2685
  dfR = list_relationships(
2710
- dataset=self.dataset, workspace=self.workspace, extended=True
2686
+ dataset=self._dataset, workspace=self._workspace, extended=True
2711
2687
  )
2712
2688
 
2713
2689
  for t in self.model.Tables:
@@ -3100,7 +3076,7 @@ class TOMWrapper:
3100
3076
  import Microsoft.AnalysisServices.Tabular as TOM
3101
3077
 
3102
3078
  def create_pattern(a, b):
3103
- return r"(?<!" + a + "\[)(?<!" + a + "'\[)" + b
3079
+ return r"(?<!" + re.escape(a) + r"\[)(?<!" + re.escape(a) + r"'\[)" + re.escape(b)
3104
3080
 
3105
3081
  for obj in self.depends_on(object=object, dependencies=dependencies):
3106
3082
  if obj.ObjectType == TOM.ObjectType.Column:
@@ -3128,7 +3104,7 @@ class TOMWrapper:
3128
3104
  usingView = False
3129
3105
 
3130
3106
  if self.is_direct_lake():
3131
- df = check_fallback_reason(dataset=self.dataset, workspace=self.workspace)
3107
+ df = check_fallback_reason(dataset=self._dataset, workspace=self._workspace)
3132
3108
  df_filt = df[df["FallbackReasonID"] == 2]
3133
3109
 
3134
3110
  if len(df_filt) > 0:
@@ -3138,7 +3114,7 @@ class TOMWrapper:
3138
3114
 
3139
3115
  def has_incremental_refresh_policy(self, table_name: str):
3140
3116
  """
3141
- Identifies whether a table has an incremental refresh policy.
3117
+ Identifies whether a table has an `incremental refresh <https://learn.microsoft.com/power-bi/connect-data/incremental-refresh-overview>`_ policy.
3142
3118
 
3143
3119
  Parameters
3144
3120
  ----------
@@ -3161,7 +3137,7 @@ class TOMWrapper:
3161
3137
 
3162
3138
  def show_incremental_refresh_policy(self, table_name: str):
3163
3139
  """
3164
- Prints the incremental refresh policy for a table.
3140
+ Prints the `incremental refresh <https://learn.microsoft.com/power-bi/connect-data/incremental-refresh-overview>`_ policy for a table.
3165
3141
 
3166
3142
  Parameters
3167
3143
  ----------
@@ -3169,11 +3145,13 @@ class TOMWrapper:
3169
3145
  Name of the table.
3170
3146
  """
3171
3147
 
3148
+ import Microsoft.AnalysisServices.Tabular as TOM
3149
+
3172
3150
  rp = self.model.Tables[table_name].RefreshPolicy
3173
3151
 
3174
3152
  if rp is None:
3175
3153
  print(
3176
- f"The '{table_name}' table in the '{self.dataset}' semantic model within the '{self.workspace}' workspace does not have an incremental refresh policy."
3154
+ f"{icons.yellow_dot} The '{table_name}' table in the '{self._dataset}' semantic model within the '{self._workspace}' workspace does not have an incremental refresh policy."
3177
3155
  )
3178
3156
  else:
3179
3157
  print(f"Table Name: {table_name}")
@@ -3181,33 +3159,33 @@ class TOMWrapper:
3181
3159
  icGran = str(rp.IncrementalGranularity).lower()
3182
3160
  if rp.RollingWindowPeriods > 1:
3183
3161
  print(
3184
- f"Archive data starting {start_bold}{rp.RollingWindowPeriods} {rwGran}s{end_bold} before refresh date."
3162
+ f"Archive data starting {icons.start_bold}{rp.RollingWindowPeriods} {rwGran}s{icons.end_bold} before refresh date."
3185
3163
  )
3186
3164
  else:
3187
3165
  print(
3188
- f"Archive data starting {start_bold}{rp.RollingWindowPeriods} {rwGran}{end_bold} before refresh date."
3166
+ f"Archive data starting {icons.start_bold}{rp.RollingWindowPeriods} {rwGran}{icons.end_bold} before refresh date."
3189
3167
  )
3190
3168
  if rp.IncrementalPeriods > 1:
3191
3169
  print(
3192
- f"Incrementally refresh data {start_bold}{rp.IncrementalPeriods} {icGran}s{end_bold} before refresh date."
3170
+ f"Incrementally refresh data {icons.start_bold}{rp.IncrementalPeriods} {icGran}s{icons.end_bold} before refresh date."
3193
3171
  )
3194
3172
  else:
3195
3173
  print(
3196
- f"Incrementally refresh data {start_bold}{rp.IncrementalPeriods} {icGran}{end_bold} before refresh date."
3174
+ f"Incrementally refresh data {icons.start_bold}{rp.IncrementalPeriods} {icGran}{icons.end_bold} before refresh date."
3197
3175
  )
3198
3176
 
3199
3177
  if rp.Mode == TOM.RefreshPolicyMode.Hybrid:
3200
3178
  print(
3201
- f"{checked} Get the latest data in real time with DirectQuery (Premium only)"
3179
+ f"{icons.checked} Get the latest data in real time with DirectQuery (Premium only)"
3202
3180
  )
3203
3181
  else:
3204
3182
  print(
3205
- f"{unchecked} Get the latest data in real time with DirectQuery (Premium only)"
3183
+ f"{icons.unchecked} Get the latest data in real time with DirectQuery (Premium only)"
3206
3184
  )
3207
3185
  if rp.IncrementalPeriodsOffset == -1:
3208
- print(f"{checked} Only refresh complete days")
3186
+ print(f"{icons.checked} Only refresh complete days")
3209
3187
  else:
3210
- print(f"{unchecked} Only refresh complete days")
3188
+ print(f"{icons.unchecked} Only refresh complete days")
3211
3189
  if len(rp.PollingExpression) > 0:
3212
3190
  pattern = r"\[([^\]]+)\]"
3213
3191
  match = re.search(pattern, rp.PollingExpression)
@@ -3215,10 +3193,10 @@ class TOMWrapper:
3215
3193
  col = match[0][1:-1]
3216
3194
  fullCol = format_dax_object_name(table_name, col)
3217
3195
  print(
3218
- f"{checked} Detect data changes: {start_bold}{fullCol}{end_bold}"
3196
+ f"{icons.checked} Detect data changes: {icons.start_bold}{fullCol}{icons.end_bold}"
3219
3197
  )
3220
3198
  else:
3221
- print(f"{unchecked} Detect data changes")
3199
+ print(f"{icons.unchecked} Detect data changes")
3222
3200
 
3223
3201
  def update_incremental_refresh_policy(
3224
3202
  self,
@@ -3231,7 +3209,7 @@ class TOMWrapper:
3231
3209
  detect_data_changes_column: Optional[str] = None,
3232
3210
  ):
3233
3211
  """
3234
- Updates the incremental refresh policy for a table within a semantic model.
3212
+ Updates the `incremental refresh <https://learn.microsoft.com/power-bi/connect-data/incremental-refresh-overview>`_ policy for a table within a semantic model.
3235
3213
 
3236
3214
  Parameters
3237
3215
  ----------
@@ -3339,7 +3317,7 @@ class TOMWrapper:
3339
3317
  detect_data_changes_column: Optional[str] = None,
3340
3318
  ):
3341
3319
  """
3342
- Adds anincremental refresh policy for a table within a semantic model.
3320
+ Adds an `incremental refresh <https://learn.microsoft.com/power-bi/connect-data/incremental-refresh-overview>`_ policy for a table within a semantic model.
3343
3321
 
3344
3322
  Parameters
3345
3323
  ----------
@@ -3514,7 +3492,7 @@ class TOMWrapper:
3514
3492
  max_parallelism: Optional[int] = 0,
3515
3493
  ):
3516
3494
  """
3517
- Applies the incremental refresh policy for a table within a semantic model.
3495
+ `Applies the incremental refresh <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.table.applyrefreshpolicy?view=analysisservices-dotnet#microsoft-analysisservices-tabular-table-applyrefreshpolicy(system-boolean-system-int32)>`_ policy for a table within a semantic model.
3518
3496
 
3519
3497
  Parameters
3520
3498
  ----------
@@ -3538,7 +3516,7 @@ class TOMWrapper:
3538
3516
  self, table_name: str, partition_name: str, expression: str
3539
3517
  ):
3540
3518
  """
3541
- Sets the data coverage definition for a partition.
3519
+ Sets the `data coverage definition <https://learn.microsoft.com/analysis-services/tom/table-partitions?view=asallproducts-allversions>`_ for a partition.
3542
3520
 
3543
3521
  Parameters
3544
3522
  ----------
@@ -3560,12 +3538,12 @@ class TOMWrapper:
3560
3538
 
3561
3539
  if not ht:
3562
3540
  print(
3563
- f"The data coverage definition property is only applicable to hybrid tables. See the documentation: {doc}."
3541
+ f"{icons.red_dot} The `data coverage definition <https://learn.microsoft.com/analysis-services/tom/table-partitions?view=asallproducts-allversions>`_ property is only applicable to `hybrid tables <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_. See the documentation: {doc}."
3564
3542
  )
3565
3543
  return
3566
3544
  if p.Mode != TOM.ModeType.DirectQuery:
3567
3545
  print(
3568
- f"The data coverage definition property is only applicable to the DirectQuery partition of a hybrid table. See the documentation: {doc}."
3546
+ f"{icons.red_dot} The `data coverage definition <https://learn.microsoft.com/analysis-services/tom/table-partitions?view=asallproducts-allversions>`_ property is only applicable to the DirectQuery partition of a `hybrid table <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_. See the documentation: {doc}."
3569
3547
  )
3570
3548
  return
3571
3549
 
@@ -3575,7 +3553,7 @@ class TOMWrapper:
3575
3553
 
3576
3554
  def set_encoding_hint(self, table_name: str, column_name: str, value: str):
3577
3555
  """
3578
- Sets the encoding hint for a column.
3556
+ Sets the `encoding hint <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.encodinghinttype?view=analysisservices-dotnet>`_ for a column.
3579
3557
 
3580
3558
  Parameters
3581
3559
  ----------
@@ -3605,7 +3583,7 @@ class TOMWrapper:
3605
3583
 
3606
3584
  def set_data_type(self, table_name: str, column_name: str, value: str):
3607
3585
  """
3608
- Sets the data type for a column.
3586
+ Sets the `data type <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.datatype?view=analysisservices-dotnet>`_ for a column.
3609
3587
 
3610
3588
  Parameters
3611
3589
  ----------
@@ -3617,6 +3595,7 @@ class TOMWrapper:
3617
3595
  The data type.
3618
3596
  `Data type valid values <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.datatype?view=analysisservices-dotnet>`_
3619
3597
  """
3598
+ import Microsoft.AnalysisServices.Tabular as TOM
3620
3599
  import System
3621
3600
 
3622
3601
  values = [
@@ -3674,7 +3653,7 @@ class TOMWrapper:
3674
3653
  t = t.capitalize()
3675
3654
  if t not in [time_intel_options]:
3676
3655
  print(
3677
- f"The '{t}' time intelligence variation is not supported. Valid options: {time_intel_options}."
3656
+ f"{icons.red_dot} The '{t}' time intelligence variation is not supported. Valid options: {time_intel_options}."
3678
3657
  )
3679
3658
  return
3680
3659
 
@@ -3685,14 +3664,14 @@ class TOMWrapper:
3685
3664
 
3686
3665
  if table_name is None:
3687
3666
  print(
3688
- f"The '{measure_name}' is not a valid measure in the '{self.dataset}' semantic model within the '{self.workspace}' workspace."
3667
+ f"{icons.red_dot} The '{measure_name}' is not a valid measure in the '{self._dataset}' semantic model within the '{self._workspace}' workspace."
3689
3668
  )
3690
3669
  return
3691
3670
 
3692
3671
  # Validate date table
3693
3672
  if not self.is_date_table(date_table):
3694
3673
  print(
3695
- f"{icons.red_dot} The '{date_table}' table is not a valid date table in the '{self.dataset}' wemantic model within the '{self.workspace}' workspace."
3674
+ f"{icons.red_dot} The '{date_table}' table is not a valid date table in the '{self._dataset}' wemantic model within the '{self._workspace}' workspace."
3696
3675
  )
3697
3676
  return
3698
3677
 
@@ -3713,25 +3692,25 @@ class TOMWrapper:
3713
3692
  )
3714
3693
 
3715
3694
  def close(self):
3716
- if not self.readonly and self.model is not None:
3695
+ if not self._readonly and self.model is not None:
3717
3696
  self.model.SaveChanges()
3718
3697
 
3719
- if len(self.tables_added) > 0:
3698
+ if len(self._tables_added) > 0:
3720
3699
  refresh_semantic_model(
3721
- dataset=self.dataset,
3722
- tables=self.tables_added,
3723
- workspace=self.workspace,
3700
+ dataset=self._dataset,
3701
+ tables=self._tables_added,
3702
+ workspace=self._workspace,
3724
3703
  )
3725
3704
  self.model = None
3726
3705
 
3727
- self.tom_server.Dispose()
3706
+ self._tom_server.Dispose()
3728
3707
 
3729
3708
 
3730
3709
  @log
3731
3710
  @contextmanager
3732
3711
  def connect_semantic_model(
3733
3712
  dataset: str, readonly: bool = True, workspace: Optional[str] = None
3734
- ):
3713
+ ) -> Iterator[TOMWrapper]:
3735
3714
  """
3736
3715
  Connects to the Tabular Object Model (TOM) within a semantic model.
3737
3716
 
@@ -3748,7 +3727,7 @@ def connect_semantic_model(
3748
3727
 
3749
3728
  Returns
3750
3729
  -------
3751
- str
3730
+ typing.Iterator[TOMWrapper]
3752
3731
  A connection to the semantic model's Tabular Object Model.
3753
3732
  """
3754
3733