semantic-link-labs 0.9.5__py3-none-any.whl → 0.9.7__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 (65) hide show
  1. {semantic_link_labs-0.9.5.dist-info → semantic_link_labs-0.9.7.dist-info}/METADATA +8 -5
  2. {semantic_link_labs-0.9.5.dist-info → semantic_link_labs-0.9.7.dist-info}/RECORD +65 -61
  3. {semantic_link_labs-0.9.5.dist-info → semantic_link_labs-0.9.7.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +19 -1
  5. sempy_labs/_ai.py +3 -1
  6. sempy_labs/_capacities.py +37 -2
  7. sempy_labs/_capacity_migration.py +11 -14
  8. sempy_labs/_connections.py +2 -4
  9. sempy_labs/_dataflows.py +2 -2
  10. sempy_labs/_dax_query_view.py +57 -0
  11. sempy_labs/_delta_analyzer.py +16 -14
  12. sempy_labs/_delta_analyzer_history.py +298 -0
  13. sempy_labs/_environments.py +8 -1
  14. sempy_labs/_eventhouses.py +5 -1
  15. sempy_labs/_external_data_shares.py +4 -10
  16. sempy_labs/_generate_semantic_model.py +2 -1
  17. sempy_labs/_graphQL.py +5 -1
  18. sempy_labs/_helper_functions.py +440 -63
  19. sempy_labs/_icons.py +6 -6
  20. sempy_labs/_kql_databases.py +5 -1
  21. sempy_labs/_list_functions.py +8 -38
  22. sempy_labs/_managed_private_endpoints.py +9 -2
  23. sempy_labs/_mirrored_databases.py +3 -1
  24. sempy_labs/_ml_experiments.py +1 -1
  25. sempy_labs/_model_bpa.py +2 -11
  26. sempy_labs/_model_bpa_bulk.py +33 -38
  27. sempy_labs/_model_bpa_rules.py +1 -1
  28. sempy_labs/_one_lake_integration.py +2 -1
  29. sempy_labs/_semantic_models.py +20 -0
  30. sempy_labs/_sql.py +6 -2
  31. sempy_labs/_sqldatabase.py +61 -100
  32. sempy_labs/_vertipaq.py +8 -11
  33. sempy_labs/_warehouses.py +14 -3
  34. sempy_labs/_workspace_identity.py +6 -0
  35. sempy_labs/_workspaces.py +42 -2
  36. sempy_labs/admin/_basic_functions.py +29 -2
  37. sempy_labs/admin/_reports.py +1 -1
  38. sempy_labs/admin/_scanner.py +2 -4
  39. sempy_labs/admin/_tenant.py +8 -3
  40. sempy_labs/directlake/_directlake_schema_compare.py +2 -1
  41. sempy_labs/directlake/_directlake_schema_sync.py +65 -19
  42. sempy_labs/directlake/_dl_helper.py +0 -6
  43. sempy_labs/directlake/_generate_shared_expression.py +19 -12
  44. sempy_labs/directlake/_guardrails.py +2 -1
  45. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +90 -57
  46. sempy_labs/directlake/_update_directlake_partition_entity.py +5 -2
  47. sempy_labs/graph/_groups.py +6 -0
  48. sempy_labs/graph/_teams.py +2 -0
  49. sempy_labs/graph/_users.py +4 -0
  50. sempy_labs/lakehouse/__init__.py +12 -3
  51. sempy_labs/lakehouse/_blobs.py +231 -0
  52. sempy_labs/lakehouse/_shortcuts.py +29 -8
  53. sempy_labs/migration/_direct_lake_to_import.py +47 -10
  54. sempy_labs/migration/_migration_validation.py +0 -4
  55. sempy_labs/report/__init__.py +4 -0
  56. sempy_labs/report/_download_report.py +4 -6
  57. sempy_labs/report/_generate_report.py +6 -6
  58. sempy_labs/report/_report_functions.py +5 -4
  59. sempy_labs/report/_report_helper.py +17 -5
  60. sempy_labs/report/_report_rebind.py +8 -6
  61. sempy_labs/report/_reportwrapper.py +17 -8
  62. sempy_labs/report/_save_report.py +147 -0
  63. sempy_labs/tom/_model.py +154 -23
  64. {semantic_link_labs-0.9.5.dist-info → semantic_link_labs-0.9.7.dist-info/licenses}/LICENSE +0 -0
  65. {semantic_link_labs-0.9.5.dist-info → semantic_link_labs-0.9.7.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  import sempy
2
- import sempy.fabric as fabric
2
+ import pandas as pd
3
3
  from sempy_labs.lakehouse import get_lakehouse_columns
4
4
  from sempy_labs.directlake._dl_helper import get_direct_lake_source
5
5
  from sempy_labs.tom import connect_semantic_model
@@ -19,8 +19,8 @@ def direct_lake_schema_sync(
19
19
  dataset: str | UUID,
20
20
  workspace: Optional[str | UUID] = None,
21
21
  add_to_model: bool = False,
22
- **kwargs,
23
- ):
22
+ remove_from_model: bool = False,
23
+ ) -> pd.DataFrame:
24
24
  """
25
25
  Shows/adds columns which exist in the lakehouse but do not exist in the semantic model (only for tables in the semantic model).
26
26
 
@@ -34,22 +34,18 @@ def direct_lake_schema_sync(
34
34
  or if no lakehouse attached, resolves to the workspace of the notebook.
35
35
  add_to_model : bool, default=False
36
36
  If set to True, columns which exist in the lakehouse but do not exist in the semantic model are added to the semantic model. No new tables are added.
37
+ remove_from_model : bool, default=False
38
+ If set to True, columns which exist in the semantic model but do not exist in the lakehouse are removed from the semantic model. No new tables are removed.
39
+
40
+ Returns
41
+ -------
42
+ pandas.DataFrame
43
+ A pandas dataframe showing the status of columns in the semantic model and lakehouse (prior to adding/removing them from the model using this function).
37
44
  """
38
45
 
39
46
  sempy.fabric._client._utils._init_analysis_services()
40
47
  import Microsoft.AnalysisServices.Tabular as TOM
41
48
 
42
- if "lakehouse" in kwargs:
43
- print(
44
- "The 'lakehouse' parameter has been deprecated as it is no longer necessary. Please remove this parameter from the function going forward."
45
- )
46
- del kwargs["lakehouse"]
47
- if "lakehouse_workspace" in kwargs:
48
- print(
49
- "The 'lakehouse_workspace' parameter has been deprecated as it is no longer necessary. Please remove this parameter from the function going forward."
50
- )
51
- del kwargs["lakehouse_workspace"]
52
-
53
49
  (workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
54
50
  (dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
55
51
 
@@ -67,14 +63,54 @@ def direct_lake_schema_sync(
67
63
  f"{icons.red_dot} This function only supports Direct Lake semantic models where the source lakehouse resides in the same workpace as the semantic model."
68
64
  )
69
65
 
70
- lakehouse_workspace = fabric.resolve_workspace_name(lakehouse_workspace_id)
66
+ lc = get_lakehouse_columns(lakehouse_id, lakehouse_workspace_id)
71
67
 
72
- lc = get_lakehouse_columns(lakehouse_name, lakehouse_workspace)
68
+ readonly = True
69
+ if add_to_model or remove_from_model:
70
+ readonly = False
71
+ df = pd.DataFrame(
72
+ columns=[
73
+ "TableName",
74
+ "ColumnName",
75
+ "SourceTableName",
76
+ "SourceColumnName",
77
+ "Status",
78
+ ]
79
+ )
73
80
 
74
81
  with connect_semantic_model(
75
- dataset=dataset_id, readonly=False, workspace=workspace_id
82
+ dataset=dataset_id, readonly=readonly, workspace=workspace_id
76
83
  ) as tom:
84
+ # Check if the columns in the semantic model exist in the lakehouse
85
+ for c in tom.all_columns():
86
+ partition_name = next(p.Name for p in c.Table.Partitions)
87
+ p = c.Table.Partitions[partition_name]
88
+ if p.SourceType == TOM.PartitionSourceType.Entity:
89
+ entity_name = p.Source.EntityName
90
+ source_column = c.SourceColumn
91
+ lc_filt = lc[
92
+ (lc["Table Name"] == entity_name)
93
+ & (lc["Column Name"] == source_column)
94
+ ]
95
+ # Remove column from model if it doesn't exist in the lakehouse
96
+ if lc_filt.empty:
97
+ new_data = {
98
+ "TableName": c.Parent.Name,
99
+ "ColumnName": c.Name,
100
+ "SourceTableName": entity_name,
101
+ "SourceColumnName": source_column,
102
+ "Status": "Not in lakehouse",
103
+ }
104
+ df = pd.concat(
105
+ [df, pd.DataFrame(new_data, index=[0])], ignore_index=True
106
+ )
107
+ if remove_from_model:
108
+ tom.remove_object(object=c)
109
+ print(
110
+ f"{icons.green_dot} The '{c.Parent.Name}'[{c.Name}] column has been removed from the '{dataset_name}' semantic model within the '{workspace_name}' workspace."
111
+ )
77
112
 
113
+ # Check if the lakehouse columns exist in the semantic model
78
114
  for i, r in lc.iterrows():
79
115
  lakeTName = r["Table Name"]
80
116
  lakeCName = r["Column Name"]
@@ -97,9 +133,17 @@ def direct_lake_schema_sync(
97
133
  c.SourceColumn == lakeCName and c.Parent.Name == table_name
98
134
  for c in tom.all_columns()
99
135
  ):
100
- print(
101
- f"{icons.yellow_dot} The '{lakeCName}' column exists in the '{lakeTName}' lakehouse table but not in the '{dataset_name}' semantic model within the '{workspace_name}' workspace."
136
+ new_data = {
137
+ "TableName": table_name,
138
+ "ColumnName": None,
139
+ "SourceTableName": lakeTName,
140
+ "SourceColumnName": lakeCName,
141
+ "Status": "Not in semantic model",
142
+ }
143
+ df = pd.concat(
144
+ [df, pd.DataFrame(new_data, index=[0])], ignore_index=True
102
145
  )
146
+
103
147
  if add_to_model:
104
148
  dt = _convert_data_type(dType)
105
149
  tom.add_data_column(
@@ -111,3 +155,5 @@ def direct_lake_schema_sync(
111
155
  print(
112
156
  f"{icons.green_dot} The '{lakeCName}' column in the '{lakeTName}' lakehouse table was added to the '{dataset_name}' semantic model within the '{workspace_name}' workspace."
113
157
  )
158
+
159
+ return df
@@ -7,7 +7,6 @@ import sempy_labs._icons as icons
7
7
  from sempy._utils._log import log
8
8
  from sempy_labs._helper_functions import (
9
9
  retry,
10
- resolve_lakehouse_name,
11
10
  _convert_data_type,
12
11
  resolve_dataset_name_and_id,
13
12
  resolve_workspace_name_and_id,
@@ -129,11 +128,6 @@ def generate_direct_lake_semantic_model(
129
128
  (workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
130
129
  if lakehouse_workspace is None:
131
130
  lakehouse_workspace = workspace
132
- if lakehouse is None:
133
- lakehouse_id = fabric.get_lakehouse_id()
134
- lakehouse_workspace_id = fabric.get_workspace_id()
135
- lakehouse_workspace = fabric.resolve_workspace_name(lakehouse_workspace_id)
136
- lakehouse = resolve_lakehouse_name(lakehouse_id, lakehouse_workspace)
137
131
 
138
132
  dfLT = get_lakehouse_tables(lakehouse=lakehouse, workspace=lakehouse_workspace)
139
133
 
@@ -1,10 +1,8 @@
1
- import sempy.fabric as fabric
2
1
  from sempy_labs._helper_functions import (
3
- resolve_lakehouse_name,
4
- resolve_lakehouse_id,
5
- resolve_warehouse_id,
6
2
  resolve_workspace_name_and_id,
7
3
  _base_api,
4
+ resolve_lakehouse_name_and_id,
5
+ resolve_item_name_and_id,
8
6
  )
9
7
  from typing import Optional
10
8
  import sempy_labs._icons as icons
@@ -15,6 +13,7 @@ def generate_shared_expression(
15
13
  item_name: Optional[str] = None,
16
14
  item_type: str = "Lakehouse",
17
15
  workspace: Optional[str | UUID] = None,
16
+ use_sql_endpoint: bool = True,
18
17
  ) -> str:
19
18
  """
20
19
  Dynamically generates the M expression used by a Direct Lake model for a given lakehouse/warehouse.
@@ -30,6 +29,9 @@ def generate_shared_expression(
30
29
  The Fabric workspace name or ID used by the item.
31
30
  Defaults to None which resolves to the workspace of the attached lakehouse
32
31
  or if no lakehouse attached, resolves to the workspace of the notebook.
32
+ use_sql_endpoint : bool, default=True
33
+ Whether to use the SQL Endpoint for the lakehouse/warehouse.
34
+ If False, the expression will be generated without using the SQL Endpoint.
33
35
 
34
36
  Returns
35
37
  -------
@@ -45,13 +47,14 @@ def generate_shared_expression(
45
47
  f"{icons.red_dot} Invalid item type. Valid options: {item_types}."
46
48
  )
47
49
 
48
- if item_name is None:
49
- item_id = fabric.get_lakehouse_id()
50
- item_name = resolve_lakehouse_name(item_id, workspace_id)
51
- elif item_name is not None and item_type == "Lakehouse":
52
- item_id = resolve_lakehouse_id(lakehouse=item_name, workspace=workspace_id)
53
- elif item_type == "Warehouse":
54
- item_id = resolve_warehouse_id(warehouse=item_name, workspace=workspace_id)
50
+ if item_type == "Lakehouse":
51
+ (item_name, item_id) = resolve_lakehouse_name_and_id(
52
+ lakehouse=item_name, workspace=workspace_id
53
+ )
54
+ else:
55
+ (item_name, item_id) = resolve_item_name_and_id(
56
+ item=item_name, type=item_type, workspace=workspace_id
57
+ )
55
58
 
56
59
  item_type_rest = f"{item_type.lower()}s"
57
60
  response = _base_api(
@@ -79,4 +82,8 @@ def generate_shared_expression(
79
82
  end_expr = "\nin\n\tdatabase"
80
83
  mid_expr = f'Sql.Database("{sqlEPCS}", "{sqlepid}")'
81
84
 
82
- return f"{start_expr}{mid_expr}{end_expr}"
85
+ # Build DL/OL expression
86
+ if not use_sql_endpoint and item_type == "Lakehouse":
87
+ return f'AzureDataLakeStorage{{"server":"onelake.dfs.fabric.microsoft.com","path":"/{workspace_id}/{item_id}/"}}'
88
+ else:
89
+ return f"{start_expr}{mid_expr}{end_expr}"
@@ -48,6 +48,7 @@ def get_sku_size(workspace: Optional[str | UUID] = None) -> str:
48
48
  str
49
49
  The SKU size for a workspace.
50
50
  """
51
+ from sempy_labs._capacities import list_capacities
51
52
 
52
53
  (workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
53
54
 
@@ -59,7 +60,7 @@ def get_sku_size(workspace: Optional[str | UUID] = None) -> str:
59
60
  )
60
61
 
61
62
  capacity_id = dfW["Capacity Id"].iloc[0]
62
- dfC = fabric.list_capacities()
63
+ dfC = list_capacities()
63
64
  dfC_filt = dfC[dfC["Id"] == capacity_id]
64
65
 
65
66
  if len(dfC_filt) == 0:
@@ -1,16 +1,64 @@
1
- import sempy.fabric as fabric
2
1
  from sempy_labs.directlake._generate_shared_expression import generate_shared_expression
3
2
  from sempy_labs._helper_functions import (
4
- resolve_lakehouse_name,
5
3
  resolve_dataset_name_and_id,
6
4
  resolve_workspace_name_and_id,
5
+ resolve_item_name_and_id,
6
+ resolve_lakehouse_name_and_id,
7
7
  )
8
+ from sempy._utils._log import log
8
9
  from sempy_labs.tom import connect_semantic_model
9
10
  from typing import Optional
10
11
  import sempy_labs._icons as icons
11
12
  from uuid import UUID
13
+ import re
12
14
 
13
15
 
16
+ def _extract_expression_list(expression):
17
+ """
18
+ Finds the pattern for DL/SQL & DL/OL expressions in the semantic model.
19
+ """
20
+
21
+ pattern_sql = r'Sql\.Database\s*\(\s*"([^"]+)"\s*,\s*"([^"]+)"\s*\)'
22
+ pattern_no_sql = r'AzureDataLakeStorage\s*\{\s*"server".*?:\s*onelake\.dfs\.fabric\.microsoft\.com"\s*,\s*"path"\s*:\s*"/([\da-fA-F-]+)\s*/\s*([\da-fA-F-]+)\s*/"\s*\}'
23
+
24
+ match_sql = re.search(pattern_sql, expression)
25
+ match_no_sql = re.search(pattern_no_sql, expression)
26
+
27
+ result = []
28
+ if match_sql:
29
+ value_1, value_2 = match_sql.groups()
30
+ result = [value_1, value_2, True]
31
+ elif match_no_sql:
32
+ value_1, value_2 = match_no_sql.groups()
33
+ result = [value_1, value_2, False]
34
+
35
+ return result
36
+
37
+
38
+ def _get_direct_lake_expressions(
39
+ dataset: str | UUID, workspace: Optional[str | UUID] = None
40
+ ) -> dict:
41
+ """
42
+ Extracts a dictionary of all Direct Lake expressions from a semantic model.
43
+ """
44
+
45
+ from sempy_labs.tom import connect_semantic_model
46
+
47
+ result = {}
48
+
49
+ with connect_semantic_model(dataset=dataset, workspace=workspace) as tom:
50
+ for e in tom.model.Expressions:
51
+ expr_name = e.Name
52
+ expr = e.Expression
53
+
54
+ list_values = _extract_expression_list(expr)
55
+ if list_values:
56
+ result[expr_name] = list_values
57
+
58
+ return result
59
+
60
+
61
+ @log
14
62
  def update_direct_lake_model_lakehouse_connection(
15
63
  dataset: str | UUID,
16
64
  workspace: Optional[str | UUID] = None,
@@ -37,54 +85,23 @@ def update_direct_lake_model_lakehouse_connection(
37
85
  or if no lakehouse attached, resolves to the workspace of the notebook.
38
86
  """
39
87
 
40
- (workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
41
- (dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
42
-
43
- if lakehouse_workspace is None:
44
- lakehouse_workspace = workspace_name
45
-
46
- if lakehouse is None:
47
- lakehouse_id = fabric.get_lakehouse_id()
48
- lakehouse = resolve_lakehouse_name(lakehouse_id, lakehouse_workspace)
49
-
50
- # Check if lakehouse is valid
51
- dfI = fabric.list_items(workspace=lakehouse_workspace, type="Lakehouse")
52
- dfI_filt = dfI[(dfI["Display Name"] == lakehouse)]
53
-
54
- if len(dfI_filt) == 0:
55
- raise ValueError(
56
- f"{icons.red_dot} The '{lakehouse}' lakehouse does not exist within the '{lakehouse_workspace}' workspace. "
57
- f"Therefore it cannot be used to support the '{dataset_name}' semantic model within the '{workspace_name}' workspace."
58
- )
59
-
60
- icons.sll_tags.append("UpdateDLConnection")
61
-
62
- shEx = generate_shared_expression(
63
- item_name=lakehouse, item_type="Lakehouse", workspace=lakehouse_workspace
64
- )
65
-
66
- with connect_semantic_model(
67
- dataset=dataset_id, readonly=False, workspace=workspace_id
68
- ) as tom:
69
-
70
- if not tom.is_direct_lake():
71
- raise ValueError(
72
- f"{icons.red_dot} The '{dataset_name}' semantic model is not in Direct Lake. This function is only applicable to Direct Lake semantic models."
73
- )
74
-
75
- tom.model.Expressions["DatabaseQuery"].Expression = shEx
76
-
77
- print(
78
- f"{icons.green_dot} The expression in the '{dataset_name}' semantic model has been updated to point to the '{lakehouse}' lakehouse in the '{lakehouse_workspace}' workspace."
88
+ update_direct_lake_model_connection(
89
+ dataset=dataset,
90
+ workspace=workspace,
91
+ source=lakehouse,
92
+ source_type="Lakehouse",
93
+ source_workspace=lakehouse_workspace,
79
94
  )
80
95
 
81
96
 
97
+ @log
82
98
  def update_direct_lake_model_connection(
83
99
  dataset: str | UUID,
84
100
  workspace: Optional[str | UUID] = None,
85
101
  source: Optional[str] = None,
86
102
  source_type: str = "Lakehouse",
87
103
  source_workspace: Optional[str | UUID] = None,
104
+ use_sql_endpoint: bool = True,
88
105
  ):
89
106
  """
90
107
  Remaps a Direct Lake semantic model's SQL Endpoint connection to a new lakehouse/warehouse.
@@ -106,7 +123,14 @@ def update_direct_lake_model_connection(
106
123
  The Fabric workspace name or ID used by the lakehouse/warehouse.
107
124
  Defaults to None which resolves to the workspace of the attached lakehouse
108
125
  or if no lakehouse attached, resolves to the workspace of the notebook.
126
+ use_sql_endpoint : bool, default=True
127
+ If True, the SQL Endpoint will be used for the connection.
128
+ If False, Direct Lake over OneLake will be used.
109
129
  """
130
+ if use_sql_endpoint:
131
+ icons.sll_tags.append("UpdateDLConnection_SQL")
132
+ else:
133
+ icons.sll_tags.append("UpdateDLConnection_DLOL")
110
134
 
111
135
  (workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
112
136
  (dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
@@ -121,23 +145,25 @@ def update_direct_lake_model_connection(
121
145
  if source_workspace is None:
122
146
  source_workspace = workspace_name
123
147
 
124
- if source is None:
125
- source_id = fabric.get_lakehouse_id()
126
- source = resolve_lakehouse_name(source_id, source_workspace)
127
- else:
128
- source_id = fabric.resolve_item_id(
129
- item_name=source, type=source_type, workspace=source_workspace
148
+ if source_type == "Lakehouse":
149
+ (source_name, source_id) = resolve_lakehouse_name_and_id(
150
+ lakehouse=source, workspace=source_workspace
130
151
  )
131
- source = fabric.resolve_item_name(
132
- item_id=source_id, workspace=source_workspace, type=source_type
152
+ else:
153
+ (source_name, source_id) = resolve_item_name_and_id(
154
+ item=source, type=source_type, workspace=source_workspace
133
155
  )
134
156
 
135
- icons.sll_tags.append("UpdateDLConnection")
136
-
137
- shEx = generate_shared_expression(
138
- item_name=source, item_type=source_type, workspace=source_workspace
157
+ shared_expression = generate_shared_expression(
158
+ item_name=source_name,
159
+ item_type=source_type,
160
+ workspace=source_workspace,
161
+ use_sql_endpoint=use_sql_endpoint,
139
162
  )
140
163
 
164
+ expression_dict = _get_direct_lake_expressions(dataset=dataset, workspace=workspace)
165
+ expressions = list(expression_dict.keys())
166
+
141
167
  with connect_semantic_model(
142
168
  dataset=dataset_id, readonly=False, workspace=workspace_id
143
169
  ) as tom:
@@ -147,8 +173,15 @@ def update_direct_lake_model_connection(
147
173
  f"{icons.red_dot} The '{dataset_name}' semantic model within the '{workspace_name}' workspace is not in Direct Lake. This function is only applicable to Direct Lake semantic models."
148
174
  )
149
175
 
150
- tom.model.Expressions["DatabaseQuery"].Expression = shEx
176
+ # Update the single connection expression
177
+ if len(expressions) == 1:
178
+ expr = expressions[0]
179
+ tom.model.Expressions[expr].Expression = shared_expression
151
180
 
152
- print(
153
- f"{icons.green_dot} The expression in the '{dataset_name}' semantic model within the '{workspace_name}' workspace has been updated to point to the '{source}' {source_type.lower()} in the '{source_workspace}' workspace."
154
- )
181
+ print(
182
+ f"{icons.green_dot} The expression in the '{dataset_name}' semantic model within the '{workspace_name}' workspace has been updated to point to the '{source}' {source_type.lower()} in the '{source_workspace}' workspace."
183
+ )
184
+ else:
185
+ print(
186
+ f"{icons.info} Multiple expressions found in the model. Please use the update_direct_lake_partition_entity function to update specific tables."
187
+ )
@@ -1,5 +1,4 @@
1
1
  import sempy
2
- import sempy.fabric as fabric
3
2
  from sempy_labs.tom import connect_semantic_model
4
3
  from sempy_labs._refresh_semantic_model import refresh_semantic_model
5
4
  from sempy_labs.directlake._dl_helper import get_direct_lake_source
@@ -7,12 +6,15 @@ from sempy_labs._helper_functions import (
7
6
  _convert_data_type,
8
7
  resolve_dataset_name_and_id,
9
8
  resolve_workspace_name_and_id,
9
+ resolve_workspace_name,
10
10
  )
11
+ from sempy._utils._log import log
11
12
  from typing import List, Optional, Union
12
13
  import sempy_labs._icons as icons
13
14
  from uuid import UUID
14
15
 
15
16
 
17
+ @log
16
18
  def update_direct_lake_partition_entity(
17
19
  dataset: str | UUID,
18
20
  table_name: Union[str, List[str]],
@@ -96,6 +98,7 @@ def update_direct_lake_partition_entity(
96
98
  )
97
99
 
98
100
 
101
+ @log
99
102
  def add_table_to_direct_lake_semantic_model(
100
103
  dataset: str | UUID,
101
104
  table_name: str,
@@ -144,7 +147,7 @@ def add_table_to_direct_lake_semantic_model(
144
147
  f"{icons.red_dot} This function only supports Direct Lake semantic models where the source lakehouse resides in the same workpace as the semantic model."
145
148
  )
146
149
 
147
- lakehouse_workspace = fabric.resolve_workspace_name(lakehouse_workspace_id)
150
+ lakehouse_workspace = resolve_workspace_name(workspace_id=lakehouse_workspace_id)
148
151
 
149
152
  with connect_semantic_model(
150
153
  dataset=dataset_id, readonly=False, workspace=workspace_id
@@ -6,6 +6,7 @@ from sempy_labs._helper_functions import (
6
6
  _create_dataframe,
7
7
  _update_dataframe_datatypes,
8
8
  )
9
+ from sempy._utils._log import log
9
10
  import sempy_labs._icons as icons
10
11
  from typing import List, Literal
11
12
 
@@ -38,6 +39,7 @@ def resolve_group_id(group: str | UUID) -> UUID:
38
39
  return group_id
39
40
 
40
41
 
42
+ @log
41
43
  def list_groups() -> pd.DataFrame:
42
44
  """
43
45
  Shows a list of groups and their properties.
@@ -158,6 +160,7 @@ def _get_group(group_id: UUID) -> pd.DataFrame:
158
160
  return df
159
161
 
160
162
 
163
+ @log
161
164
  def list_group_members(group: str | UUID) -> pd.DataFrame:
162
165
  """
163
166
  Shows a list of the members of a group.
@@ -217,6 +220,7 @@ def list_group_members(group: str | UUID) -> pd.DataFrame:
217
220
  return df
218
221
 
219
222
 
223
+ @log
220
224
  def list_group_owners(group: str | UUID) -> pd.DataFrame:
221
225
  """
222
226
  Shows a list of the owners of a group.
@@ -332,6 +336,7 @@ def _base_add_to_group(
332
336
  )
333
337
 
334
338
 
339
+ @log
335
340
  def add_group_members(
336
341
  group: str | UUID,
337
342
  user: str | UUID | List[str | UUID],
@@ -376,6 +381,7 @@ def add_group_owners(
376
381
  _base_add_to_group(group=group, object=user, object_type="owners")
377
382
 
378
383
 
384
+ @log
379
385
  def renew_group(group: str | UUID):
380
386
  """
381
387
  Renews the group.
@@ -1,5 +1,6 @@
1
1
  import pandas as pd
2
2
  from uuid import UUID
3
+ from sempy._utils._log import log
3
4
  from sempy_labs._helper_functions import (
4
5
  _base_api,
5
6
  _create_dataframe,
@@ -7,6 +8,7 @@ from sempy_labs._helper_functions import (
7
8
  )
8
9
 
9
10
 
11
+ @log
10
12
  def list_teams() -> pd.DataFrame:
11
13
  """
12
14
  Shows a list of teams and their properties.
@@ -7,6 +7,7 @@ from sempy_labs._helper_functions import (
7
7
  _base_api,
8
8
  _create_dataframe,
9
9
  )
10
+ from sempy._utils._log import log
10
11
 
11
12
 
12
13
  def resolve_user_id(user: str | UUID) -> UUID:
@@ -33,6 +34,7 @@ def resolve_user_id(user: str | UUID) -> UUID:
33
34
  return result.get("id")
34
35
 
35
36
 
37
+ @log
36
38
  def get_user(user: str | UUID) -> pd.DataFrame:
37
39
  """
38
40
  Shows properties of a given user.
@@ -70,6 +72,7 @@ def get_user(user: str | UUID) -> pd.DataFrame:
70
72
  return pd.DataFrame([new_data])
71
73
 
72
74
 
75
+ @log
73
76
  def list_users() -> pd.DataFrame:
74
77
  """
75
78
  Shows a list of users and their properties.
@@ -120,6 +123,7 @@ def list_users() -> pd.DataFrame:
120
123
  return df
121
124
 
122
125
 
126
+ @log
123
127
  def send_mail(
124
128
  user: UUID | str,
125
129
  subject: str,
@@ -1,12 +1,15 @@
1
- from sempy_labs.lakehouse._get_lakehouse_columns import get_lakehouse_columns
2
- from sempy_labs.lakehouse._get_lakehouse_tables import get_lakehouse_tables
1
+ from sempy_labs.lakehouse._get_lakehouse_columns import (
2
+ get_lakehouse_columns,
3
+ )
4
+ from sempy_labs.lakehouse._get_lakehouse_tables import (
5
+ get_lakehouse_tables,
6
+ )
3
7
  from sempy_labs.lakehouse._lakehouse import (
4
8
  lakehouse_attached,
5
9
  optimize_lakehouse_tables,
6
10
  vacuum_lakehouse_tables,
7
11
  run_table_maintenance,
8
12
  )
9
-
10
13
  from sempy_labs.lakehouse._shortcuts import (
11
14
  # create_shortcut,
12
15
  create_shortcut_onelake,
@@ -14,6 +17,10 @@ from sempy_labs.lakehouse._shortcuts import (
14
17
  reset_shortcut_cache,
15
18
  list_shortcuts,
16
19
  )
20
+ from sempy_labs.lakehouse._blobs import (
21
+ recover_lakehouse_object,
22
+ list_blobs,
23
+ )
17
24
 
18
25
  __all__ = [
19
26
  "get_lakehouse_columns",
@@ -27,4 +34,6 @@ __all__ = [
27
34
  "reset_shortcut_cache",
28
35
  "run_table_maintenance",
29
36
  "list_shortcuts",
37
+ "recover_lakehouse_object",
38
+ "list_blobs",
30
39
  ]