semantic-link-labs 0.9.10__py3-none-any.whl → 0.9.11__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 (36) hide show
  1. {semantic_link_labs-0.9.10.dist-info → semantic_link_labs-0.9.11.dist-info}/METADATA +27 -21
  2. {semantic_link_labs-0.9.10.dist-info → semantic_link_labs-0.9.11.dist-info}/RECORD +34 -29
  3. {semantic_link_labs-0.9.10.dist-info → semantic_link_labs-0.9.11.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +22 -1
  5. sempy_labs/_delta_analyzer.py +9 -8
  6. sempy_labs/_environments.py +19 -1
  7. sempy_labs/_generate_semantic_model.py +1 -1
  8. sempy_labs/_helper_functions.py +193 -134
  9. sempy_labs/_kusto.py +25 -23
  10. sempy_labs/_list_functions.py +13 -35
  11. sempy_labs/_model_bpa_rules.py +13 -3
  12. sempy_labs/_notebooks.py +44 -11
  13. sempy_labs/_semantic_models.py +93 -1
  14. sempy_labs/_sql.py +3 -2
  15. sempy_labs/_tags.py +194 -0
  16. sempy_labs/_variable_libraries.py +89 -0
  17. sempy_labs/_vpax.py +386 -0
  18. sempy_labs/admin/__init__.py +8 -0
  19. sempy_labs/admin/_tags.py +126 -0
  20. sempy_labs/directlake/_generate_shared_expression.py +5 -1
  21. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +55 -5
  22. sempy_labs/dotnet_lib/dotnet.runtime.config.json +10 -0
  23. sempy_labs/lakehouse/__init__.py +16 -0
  24. sempy_labs/lakehouse/_blobs.py +115 -63
  25. sempy_labs/lakehouse/_get_lakehouse_tables.py +1 -13
  26. sempy_labs/lakehouse/_helper.py +211 -0
  27. sempy_labs/lakehouse/_lakehouse.py +1 -1
  28. sempy_labs/lakehouse/_livy_sessions.py +137 -0
  29. sempy_labs/report/_download_report.py +1 -1
  30. sempy_labs/report/_generate_report.py +5 -1
  31. sempy_labs/report/_reportwrapper.py +31 -18
  32. sempy_labs/tom/_model.py +83 -21
  33. sempy_labs/report/_bpareporttemplate/.pbi/localSettings.json +0 -9
  34. sempy_labs/report/_bpareporttemplate/.platform +0 -11
  35. {semantic_link_labs-0.9.10.dist-info → semantic_link_labs-0.9.11.dist-info}/licenses/LICENSE +0 -0
  36. {semantic_link_labs-0.9.10.dist-info → semantic_link_labs-0.9.11.dist-info}/top_level.txt +0 -0
@@ -105,27 +105,40 @@ class ReportWrapper:
105
105
  )
106
106
  )
107
107
 
108
+ report_level_measures = list(
109
+ self.list_report_level_measures()["Measure Name"].values
110
+ )
108
111
  with connect_semantic_model(
109
112
  dataset=dataset_id, readonly=True, workspace=dataset_workspace_id
110
113
  ) as tom:
111
- for index, row in dataframe.iterrows():
112
- obj_type = row["Object Type"]
113
- if obj_type == "Measure":
114
- dataframe.at[index, "Valid Semantic Model Object"] = any(
115
- o.Name == row["Object Name"] for o in tom.all_measures()
116
- )
117
- elif obj_type == "Column":
118
- dataframe.at[index, "Valid Semantic Model Object"] = any(
119
- format_dax_object_name(c.Parent.Name, c.Name)
120
- == format_dax_object_name(row["Table Name"], row["Object Name"])
121
- for c in tom.all_columns()
122
- )
123
- elif obj_type == "Hierarchy":
124
- dataframe.at[index, "Valid Semantic Model Object"] = any(
125
- format_dax_object_name(h.Parent.Name, h.Name)
126
- == format_dax_object_name(row["Table Name"], row["Object Name"])
127
- for h in tom.all_hierarchies()
128
- )
114
+ measure_names = {m.Name for m in tom.all_measures()}
115
+ measure_names.update(report_level_measures)
116
+ column_names = {
117
+ format_dax_object_name(c.Parent.Name, c.Name) for c in tom.all_columns()
118
+ }
119
+ hierarchy_names = {
120
+ format_dax_object_name(h.Parent.Name, h.Name)
121
+ for h in tom.all_hierarchies()
122
+ }
123
+
124
+ # Vectorized checks
125
+ def is_valid(row):
126
+ obj_type = row["Object Type"]
127
+ obj_name = row["Object Name"]
128
+ if obj_type == "Measure":
129
+ return obj_name in measure_names
130
+ elif obj_type == "Column":
131
+ return (
132
+ format_dax_object_name(row["Table Name"], obj_name) in column_names
133
+ )
134
+ elif obj_type == "Hierarchy":
135
+ return (
136
+ format_dax_object_name(row["Table Name"], obj_name)
137
+ in hierarchy_names
138
+ )
139
+ return False
140
+
141
+ dataframe["Valid Semantic Model Object"] = dataframe.apply(is_valid, axis=1)
129
142
  return dataframe
130
143
 
131
144
  def _update_single_file(self, file_name: str, new_payload):
sempy_labs/tom/_model.py CHANGED
@@ -802,23 +802,27 @@ class TOMWrapper:
802
802
  if permission not in ["Read", "None", "Default"]:
803
803
  raise ValueError(f"{icons.red_dot} Invalid 'permission' value.")
804
804
 
805
- cp = TOM.ColumnPermission()
806
- cp.Column = self.model.Tables[table_name].Columns[column_name]
807
- cp.MetadataPermission = System.Enum.Parse(TOM.MetadataPermission, permission)
808
-
809
- if any(
810
- c.Name == column_name and t.Name == table_name and r.Name == role_name
811
- for r in self.model.Roles
812
- for t in r.TablePermissions
813
- for c in t.ColumnPermissions
814
- ):
815
- self.model.Roles[role_name].TablePermissions[table_name].ColumnPermissions[
805
+ r = self.model.Roles[role_name]
806
+ tables = [t.Name for t in r.TablePermissions]
807
+ # Add table permission if it does not exist
808
+ if table_name not in tables:
809
+ tp = TOM.TablePermission()
810
+ tp.Table = self.model.Tables[table_name]
811
+ r.TablePermissions.Add(tp)
812
+ columns = [c.Name for c in r.TablePermissions[table_name].ColumnPermissions]
813
+ # Add column permission if it does not exist
814
+ if column_name not in columns:
815
+ cp = TOM.ColumnPermission()
816
+ cp.Column = self.model.Tables[table_name].Columns[column_name]
817
+ cp.MetadataPermission = System.Enum.Parse(
818
+ TOM.MetadataPermission, permission
819
+ )
820
+ r.TablePermissions[table_name].ColumnPermissions.Add(cp)
821
+ # Set column permission if it already exists
822
+ else:
823
+ r.TablePermissions[table_name].ColumnPermissions[
816
824
  column_name
817
825
  ].MetadataPermission = System.Enum.Parse(TOM.MetadataPermission, permission)
818
- else:
819
- self.model.Roles[role_name].TablePermissions[
820
- table_name
821
- ].ColumnPermissions.Add(cp)
822
826
 
823
827
  def add_hierarchy(
824
828
  self,
@@ -3662,25 +3666,27 @@ class TOMWrapper:
3662
3666
  import Microsoft.AnalysisServices.Tabular as TOM
3663
3667
  import System
3664
3668
 
3665
- if not self.has_incremental_refresh_policy(table_name=table_name):
3669
+ if not self.has_incremental_refresh_policy(
3670
+ object=self.model.Tables[table_name]
3671
+ ):
3666
3672
  print(
3667
3673
  f"The '{table_name}' table does not have an incremental refresh policy."
3668
3674
  )
3669
3675
  return
3670
3676
 
3671
- incGran = ["Day", "Month", "Quarter", "Year"]
3677
+ granularities = ["Day", "Month", "Quarter", "Year"]
3672
3678
 
3673
3679
  incremental_granularity = incremental_granularity.capitalize()
3674
3680
  rolling_window_granularity = rolling_window_granularity.capitalize()
3675
3681
 
3676
- if incremental_granularity not in incGran:
3682
+ if incremental_granularity not in granularities:
3677
3683
  raise ValueError(
3678
- f"{icons.red_dot} Invalid 'incremental_granularity' value. Please choose from the following options: {incGran}."
3684
+ f"{icons.red_dot} Invalid 'incremental_granularity' value. Please choose from the following options: {granularities}."
3679
3685
  )
3680
3686
 
3681
- if rolling_window_granularity not in incGran:
3687
+ if rolling_window_granularity not in granularities:
3682
3688
  raise ValueError(
3683
- f"{icons.red_dot} Invalid 'rolling_window_granularity' value. Please choose from the following options: {incGran}."
3689
+ f"{icons.red_dot} Invalid 'rolling_window_granularity' value. Please choose from the following options: {granularities}."
3684
3690
  )
3685
3691
 
3686
3692
  if rolling_window_periods < 1:
@@ -5076,6 +5082,62 @@ class TOMWrapper:
5076
5082
  f"{icons.green_dot} The '{table_name}' table has been converted to Import mode."
5077
5083
  )
5078
5084
 
5085
+ def copy_object(
5086
+ self,
5087
+ object,
5088
+ target_dataset: str | UUID,
5089
+ target_workspace: Optional[str | UUID] = None,
5090
+ readonly: bool = False,
5091
+ ):
5092
+ """
5093
+ Copies a semantic model object from the current semantic model to the target semantic model.
5094
+
5095
+ Parameters
5096
+ ----------
5097
+ object : TOM Object
5098
+ The TOM object to be copied to the target semantic model. For example: tom.model.Tables['Sales'].
5099
+ target_dataset : str | uuid.UUID
5100
+ Name or ID of the target semantic model.
5101
+ target_workspace : str | uuid.UUID, default=None
5102
+ The Fabric workspace name or ID.
5103
+ Defaults to None which resolves to the workspace of the attached lakehouse
5104
+ or if no lakehouse attached, resolves to the workspace of the notebook.
5105
+ readonly : bool, default=False
5106
+ Whether the connection is read-only or read/write. Setting this to False enables read/write which saves the changes made back to the server.
5107
+ """
5108
+
5109
+ import Microsoft.AnalysisServices.Tabular as TOM
5110
+
5111
+ clone = object.Clone()
5112
+ with connect_semantic_model(
5113
+ dataset=target_dataset,
5114
+ workspace=target_workspace,
5115
+ readonly=readonly,
5116
+ ) as target_tom:
5117
+ if isinstance(object, TOM.Table):
5118
+ target_tom.model.Tables.Add(clone)
5119
+ elif isinstance(object, TOM.Column):
5120
+ target_tom.model.Tables[object.Parent.Name].Columns.Add(clone)
5121
+ elif isinstance(object, TOM.Measure):
5122
+ target_tom.model.Tables[object.Parent.Name].Measures.Add(clone)
5123
+ elif isinstance(object, TOM.Hierarchy):
5124
+ target_tom.model.Tables[object.Parent.Name].Hierarchies.Add(clone)
5125
+ elif isinstance(object, TOM.Level):
5126
+ target_tom.model.Tables[object.Parent.Parent.Name].Hierarchies[
5127
+ object.Parent.Name
5128
+ ].Levels.Add(clone)
5129
+ elif isinstance(object, TOM.Role):
5130
+ target_tom.model.Roles.Add(clone)
5131
+ elif isinstance(object, TOM.Relationship):
5132
+ target_tom.model.Relationships.Add(clone)
5133
+ else:
5134
+ raise NotImplementedError(
5135
+ f"{icons.red_dot} The '{object.ObjectType}' object type is not supported."
5136
+ )
5137
+ print(
5138
+ f"{icons.green_dot} The '{object.Name}' {str(object.ObjectType).lower()} has been copied to the '{target_dataset}' semantic model within the '{target_workspace}' workspace."
5139
+ )
5140
+
5079
5141
  def close(self):
5080
5142
 
5081
5143
  if not self._readonly and self.model is not None:
@@ -1,9 +0,0 @@
1
- {
2
- "version": "1.0",
3
- "remoteArtifacts": [
4
- {
5
- "reportId": "6a91c344-dba8-4ebf-bedb-e07134f2a204"
6
- }
7
- ],
8
- "securityBindingsSignature": "AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAMAVu7l76YU6Sl11KOiJdgQAAAAACAAAAAAAQZgAAAAEAACAAAAD1Ty+c7tZLT9/Sjguxhn/5ivfLWfUMNtgudyJ3BKzzZgAAAAAOgAAAAAIAACAAAABAyGf+iKMwvmNtcoRczjgebeIm0nlc9SFYTBYv3N7yvVADAADQN3JsIsvJUcKKc9WMo2EhiE21odezpd35tb+yudHwA/RYhypMA3fwiCTwArLefBZQ3vZ7KYh4MjihXS07i9o1XVqxAmDoli83Yhs/Wei+0HIfYOT5HOVHLUEul5x41Yx/7Bdfhc881SK6IoaJogBdwsiJVxPne+niMYqJQA6qLEPyJ33g6ucUxLA40lwdbN2cMWFzRn6tymmicDPwH0hcGPDMWwseAU+OuUeidkneRWhUGs6lkiiXLiO6kmY5RKq+S4FdtR19/e1B6EjAd94zSw+M5jQzYxn4eCZzWYiB+8Zd/jy07lfyLoGwagNqiQzbcNONqQd5w0n+8/+n4zGkBi2UojfRXoGaYDirQeZMTbt3pfPx2PArxsJ8dF0iT634pHiCF1ZFdtY+79JaFLUUG+Yf7JJv8IxuuuF74tAp4NYmuOij4hTDaf8Jafa5IoRVh7ICkwrjJyVQ8dG7I3tr0VvR+toBPG3Zlbm9BijcaBxhh1AINhnRAIkENOnPFQVH7l3Ml7B60H8Tst6ic3ihCCMYjtmN+NNWqFrJKT2trilh5TAxN+ei4H5fPwM9S7zb2bH5jhExcYTtoe7iCzxOvBsoYoFM+7FMjn9R2FATNICktYdbKDo1Of+u4oZ1+RsvBHQBVaMhSCoZ7+K5T5pZayNK3V2UID3wOuLOYvouxXXr4NVFsdgiV2oMuxTWeqmd/4bLxeqe3uTkGFmQU4mumF2YVsNbdO3IcRXhhrCCZ27ffzXBsH+lE3EhusD37Z0dsVbVVlG8AHXCh7Atgd8n73/eSI5mvj36DCOSRBVauItIATIa2FXueKA7vU6lRDYBSX8FCC2qkeN6dWpMoN5uXXEBsb5Yot1Fgrovcyl5lk7rh772Xon4FaIYFHZpklsY3JK5EXp3bF8UOE6ByN1ZucmkGgYRcTT/up/Uc86TLN6env9XXL4FQYPlReiOGWKBLVi9OoXGRLDshspniULtV3EwQ6WsjF2AyQ+WdLj3bbWKzG5Mg9jvANLrjycZAGWskh4X5JDGiv4TiJmnYQ/xPZAKKiowpVIHikLeG76uXFI+bxtpihV9+DaEJy4UxisHQxwuvUsQs38u3SHgpJmT8CNssZl41+T/IJdoQwJFLUAAAACnUQZGV9DvcOyrj8HBpXBVB5PuOQDxLB4HZOevHqCB5dc5z787E93B51QmN7I15fF6GCdWwN5f94gv1er2dtN3"
9
- }
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
3
- "metadata": {
4
- "type": "Report",
5
- "displayName": "BPAReport"
6
- },
7
- "config": {
8
- "version": "2.0",
9
- "logicalId": "a201f2cd-fd25-465f-bfbc-33b151e38b31"
10
- }
11
- }