semantic-link-labs 0.9.4__py3-none-any.whl → 0.9.6__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 (71) hide show
  1. {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/METADATA +19 -2
  2. {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/RECORD +71 -64
  3. {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +33 -4
  5. sempy_labs/_capacities.py +59 -128
  6. sempy_labs/_capacity_migration.py +19 -21
  7. sempy_labs/_connections.py +2 -4
  8. sempy_labs/_dashboards.py +60 -0
  9. sempy_labs/_data_pipelines.py +5 -31
  10. sempy_labs/_dataflows.py +2 -2
  11. sempy_labs/_dax_query_view.py +55 -0
  12. sempy_labs/_delta_analyzer.py +16 -14
  13. sempy_labs/_environments.py +28 -49
  14. sempy_labs/_eventhouses.py +27 -53
  15. sempy_labs/_eventstreams.py +16 -34
  16. sempy_labs/_external_data_shares.py +4 -10
  17. sempy_labs/_gateways.py +4 -4
  18. sempy_labs/_generate_semantic_model.py +2 -2
  19. sempy_labs/_git.py +90 -1
  20. sempy_labs/_graphQL.py +8 -21
  21. sempy_labs/_helper_functions.py +440 -91
  22. sempy_labs/_kql_databases.py +24 -35
  23. sempy_labs/_kql_querysets.py +15 -32
  24. sempy_labs/_list_functions.py +17 -192
  25. sempy_labs/_managed_private_endpoints.py +9 -2
  26. sempy_labs/_mirrored_databases.py +17 -49
  27. sempy_labs/_ml_experiments.py +6 -31
  28. sempy_labs/_ml_models.py +4 -28
  29. sempy_labs/_model_bpa.py +4 -11
  30. sempy_labs/_model_bpa_bulk.py +23 -27
  31. sempy_labs/_mounted_data_factories.py +119 -0
  32. sempy_labs/_notebooks.py +16 -26
  33. sempy_labs/_one_lake_integration.py +2 -1
  34. sempy_labs/_semantic_models.py +20 -0
  35. sempy_labs/_sql.py +13 -8
  36. sempy_labs/_sqldatabase.py +61 -100
  37. sempy_labs/_utils.py +42 -0
  38. sempy_labs/_vertipaq.py +25 -13
  39. sempy_labs/_warehouses.py +19 -20
  40. sempy_labs/_workloads.py +23 -9
  41. sempy_labs/_workspace_identity.py +6 -0
  42. sempy_labs/_workspaces.py +55 -7
  43. sempy_labs/admin/__init__.py +21 -1
  44. sempy_labs/admin/_apps.py +1 -1
  45. sempy_labs/admin/_artifacts.py +62 -0
  46. sempy_labs/admin/_basic_functions.py +3 -54
  47. sempy_labs/admin/_capacities.py +61 -0
  48. sempy_labs/admin/_reports.py +74 -0
  49. sempy_labs/admin/_scanner.py +2 -2
  50. sempy_labs/admin/_shared.py +4 -2
  51. sempy_labs/admin/_users.py +133 -0
  52. sempy_labs/admin/_workspaces.py +148 -0
  53. sempy_labs/directlake/_directlake_schema_compare.py +2 -1
  54. sempy_labs/directlake/_directlake_schema_sync.py +65 -19
  55. sempy_labs/directlake/_dl_helper.py +0 -6
  56. sempy_labs/directlake/_generate_shared_expression.py +10 -11
  57. sempy_labs/directlake/_guardrails.py +2 -1
  58. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +12 -25
  59. sempy_labs/directlake/_update_directlake_partition_entity.py +11 -3
  60. sempy_labs/lakehouse/__init__.py +2 -0
  61. sempy_labs/lakehouse/_lakehouse.py +6 -7
  62. sempy_labs/lakehouse/_shortcuts.py +198 -57
  63. sempy_labs/migration/_migration_validation.py +0 -4
  64. sempy_labs/report/_download_report.py +4 -6
  65. sempy_labs/report/_generate_report.py +15 -23
  66. sempy_labs/report/_report_bpa.py +12 -19
  67. sempy_labs/report/_report_functions.py +2 -1
  68. sempy_labs/report/_report_rebind.py +8 -6
  69. sempy_labs/tom/_model.py +34 -16
  70. {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/LICENSE +0 -0
  71. {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,148 @@
1
+ from sempy_labs._helper_functions import (
2
+ _base_api,
3
+ _build_url,
4
+ _encode_user,
5
+ )
6
+ from uuid import UUID
7
+ from typing import Optional
8
+ from sempy_labs.admin._basic_functions import (
9
+ _resolve_workspace_name_and_id,
10
+ )
11
+ import sempy_labs._icons as icons
12
+
13
+
14
+ def add_user_to_workspace(
15
+ user: str | UUID,
16
+ role: str = "Member",
17
+ principal_type: str = "User",
18
+ workspace: Optional[str | UUID] = None,
19
+ ):
20
+ """
21
+ Grants user permissions to the specified workspace.
22
+
23
+ This is a wrapper function for the following API: `Admin - Groups AddUserAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-add-user-as-admin>`_.
24
+
25
+ Parameters
26
+ ----------
27
+ user : str | uuid.UUID
28
+ The user identifier or email address. For service principals and groups you must use the user identifier.
29
+ role : str, default="Member"
30
+ The role of the user in the workspace. Options are: 'Admin', 'Contributor', 'Member', 'None', 'Viewer'.
31
+ principal_type : str, default="User"
32
+ The principal type of the user. Options are: 'App', 'Group', 'None', 'User'.
33
+ workspace : str | uuid.UUID, default=None
34
+ The Fabric workspace name or ID.
35
+ Defaults to None which resolves to the workspace of the attached lakehouse
36
+ or if no lakehouse attached, resolves to the workspace of the notebook.
37
+ """
38
+
39
+ (workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
40
+
41
+ # Validation
42
+ role = role.capitalize()
43
+ roles = ["Admin", "Contributor", "Member", "None", "Viewer"]
44
+ if role not in roles:
45
+ raise ValueError(f"{icons.red_dot} Invalid role. Please choose from {roles}")
46
+ principal_types = ["App", "Group", "None", "User"]
47
+ if principal_type not in principal_types:
48
+ raise ValueError(
49
+ f"{icons.red_dot} Invalid principal type. Please choose from {principal_types}"
50
+ )
51
+
52
+ user = _encode_user(user)
53
+
54
+ payload = {
55
+ "identifier": user, # identifier or emailAddress?
56
+ "principalType": principal_type,
57
+ "groupUserAccessRight": role,
58
+ }
59
+
60
+ _base_api(
61
+ request=f"/v1.0/myorg/admin/groups/{workspace_id}/users",
62
+ method="post",
63
+ payload=payload,
64
+ )
65
+
66
+ print(
67
+ f"{icons.green_dot} The '{user}' user has been added with '{role.lower()}' permissions to the '{workspace_name}' workspace."
68
+ )
69
+
70
+
71
+ def delete_user_from_workspace(
72
+ user: str | UUID,
73
+ workspace: Optional[str | UUID] = None,
74
+ is_group: Optional[bool] = None,
75
+ profile_id: Optional[str] = None,
76
+ ):
77
+ """
78
+ Removes user permissions from the specified workspace.
79
+
80
+ This is a wrapper function for the following API: `Admin - Groups DeleteUserAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-delete-user-as-admin>`_.
81
+
82
+ Parameters
83
+ ----------
84
+ user : str | uuid.UUID
85
+ The user identifier or email address. For service principals and groups you must use the user identifier.
86
+ workspace : str | uuid.UUID, default=None
87
+ The Fabric workspace name or ID.
88
+ Defaults to None which resolves to the workspace of the attached lakehouse
89
+ or if no lakehouse attached, resolves to the workspace of the notebook.
90
+ is_group : bool, default=None
91
+ Whether a given user is a group or not. This parameter is required when user to delete is group.
92
+ profile_id : str, default=None
93
+ The service principal profile ID to delete.
94
+ """
95
+
96
+ (workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
97
+
98
+ user = _encode_user(user)
99
+ url = f"/v1.0/myorg/admin/groups/{workspace_id}/users/{user}"
100
+
101
+ params = {}
102
+ if profile_id is not None:
103
+ params["profileId"] = profile_id
104
+ if is_group is not None:
105
+ params["isGroup"] = is_group
106
+
107
+ url = _build_url(url, params)
108
+
109
+ _base_api(
110
+ request=url,
111
+ method="delete",
112
+ )
113
+
114
+ print(
115
+ f"{icons.green_dot} The '{user}' user has been removed from the '{workspace_name}' workspace."
116
+ )
117
+
118
+
119
+ def restore_deleted_workspace(workspace_id: UUID, name: str, email_address: str):
120
+ """
121
+ Restores a deleted workspace.
122
+
123
+ This is a wrapper function for the following API: `Admin - Groups RestoreDeletedGroupAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-restore-deleted-group-as-admin>`_.
124
+
125
+ Parameters
126
+ ----------
127
+ workspace_id : uuid.UUID
128
+ The ID of the workspace to restore.
129
+ name : str
130
+ The name of the group to be restored
131
+ email_address : str
132
+ The email address of the owner of the group to be restored
133
+ """
134
+
135
+ payload = {
136
+ "name": name,
137
+ "emailAddress": email_address,
138
+ }
139
+
140
+ _base_api(
141
+ request=f"/v1.0/myorg/admin/groups/{workspace_id}/restore",
142
+ method="post",
143
+ payload=payload,
144
+ )
145
+
146
+ print(
147
+ f"{icons.green_dot} The '{workspace_id}' workspace has been restored as '{name}'."
148
+ )
@@ -4,6 +4,7 @@ from sempy_labs._helper_functions import (
4
4
  format_dax_object_name,
5
5
  resolve_workspace_name_and_id,
6
6
  resolve_dataset_name_and_id,
7
+ resolve_workspace_name,
7
8
  )
8
9
  from IPython.display import display
9
10
  from sempy_labs.lakehouse import get_lakehouse_columns
@@ -70,7 +71,7 @@ def direct_lake_schema_compare(
70
71
  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."
71
72
  )
72
73
 
73
- lakehouse_workspace = fabric.resolve_workspace_name(lakehouse_workspace_id)
74
+ lakehouse_workspace = resolve_workspace_name(workspace_id=lakehouse_workspace_id)
74
75
  dfT = fabric.list_tables(dataset=dataset_id, workspace=workspace_id)
75
76
  dfC = fabric.list_columns(dataset=dataset_id, workspace=workspace_id)
76
77
  lc = get_lakehouse_columns(lakehouse_name, lakehouse_workspace)
@@ -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
@@ -45,13 +43,14 @@ def generate_shared_expression(
45
43
  f"{icons.red_dot} Invalid item type. Valid options: {item_types}."
46
44
  )
47
45
 
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)
46
+ if item_type == "Lakehouse":
47
+ (item_name, item_id) = resolve_lakehouse_name_and_id(
48
+ lakehouse=item_name, workspace=workspace_id
49
+ )
50
+ else:
51
+ (item_name, item_id) = resolve_item_name_and_id(
52
+ item=item_name, type=item_type, workspace=workspace_id
53
+ )
55
54
 
56
55
  item_type_rest = f"{item_type.lower()}s"
57
56
  response = _base_api(
@@ -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:
@@ -4,6 +4,8 @@ from sempy_labs._helper_functions import (
4
4
  resolve_lakehouse_name,
5
5
  resolve_dataset_name_and_id,
6
6
  resolve_workspace_name_and_id,
7
+ resolve_item_name_and_id,
8
+ resolve_lakehouse_name_and_id,
7
9
  )
8
10
  from sempy_labs.tom import connect_semantic_model
9
11
  from typing import Optional
@@ -40,22 +42,9 @@ def update_direct_lake_model_lakehouse_connection(
40
42
  (workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
41
43
  (dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
42
44
 
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
- )
45
+ (lakehouse_name, lakehouse_id) = resolve_lakehouse_name_and_id(
46
+ lakehouse=lakehouse, workspace=lakehouse_workspace
47
+ )
59
48
 
60
49
  icons.sll_tags.append("UpdateDLConnection")
61
50
 
@@ -121,21 +110,19 @@ def update_direct_lake_model_connection(
121
110
  if source_workspace is None:
122
111
  source_workspace = workspace_name
123
112
 
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
113
+ if source_type == "Lakehouse":
114
+ (source_name, source_id) = resolve_lakehouse_name_and_id(
115
+ lakehouse=source, workspace=source_workspace
130
116
  )
131
- source = fabric.resolve_item_name(
132
- item_id=source_id, workspace=source_workspace, type=source_type
117
+ else:
118
+ (source_name, source_id) = resolve_item_name_and_id(
119
+ item=source, type=source_type, workspace=source_workspace
133
120
  )
134
121
 
135
122
  icons.sll_tags.append("UpdateDLConnection")
136
123
 
137
124
  shEx = generate_shared_expression(
138
- item_name=source, item_type=source_type, workspace=source_workspace
125
+ item_name=source_name, item_type=source_type, workspace=source_workspace
139
126
  )
140
127
 
141
128
  with connect_semantic_model(
@@ -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,6 +6,7 @@ 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
11
  from typing import List, Optional, Union
12
12
  import sempy_labs._icons as icons
@@ -17,6 +17,7 @@ def update_direct_lake_partition_entity(
17
17
  dataset: str | UUID,
18
18
  table_name: Union[str, List[str]],
19
19
  entity_name: Union[str, List[str]],
20
+ schema: Optional[str] = None,
20
21
  workspace: Optional[str | UUID] = None,
21
22
  ):
22
23
  """
@@ -30,6 +31,9 @@ def update_direct_lake_partition_entity(
30
31
  Name of the table(s) in the semantic model.
31
32
  entity_name : str, List[str]
32
33
  Name of the lakehouse table to be mapped to the semantic model table.
34
+ schema : str, default=None
35
+ The schema of the lakehouse table to be mapped to the semantic model table.
36
+ Defaults to None which resolves to the existing schema of the lakehouse table.
33
37
  workspace : str | uuid.UUID, default=None
34
38
  The Fabric workspace name or ID in which the semantic model exists.
35
39
  Defaults to None which resolves to the workspace of the attached lakehouse
@@ -79,9 +83,13 @@ def update_direct_lake_partition_entity(
79
83
  tom.model.Tables[tName].Partitions[part_name].Source.EntityName = eName
80
84
 
81
85
  # Update source lineage tag
82
- schema = (
86
+ existing_schema = (
83
87
  tom.model.Tables[tName].Partitions[part_name].Source.SchemaName or "dbo"
84
88
  )
89
+ if schema is None:
90
+ schema = existing_schema
91
+
92
+ tom.model.Tables[tName].Partitions[part_name].Source.SchemaName = schema
85
93
  tom.model.Tables[tName].SourceLineageTag = f"[{schema}].[{eName}]"
86
94
  print(
87
95
  f"{icons.green_dot} The '{tName}' table in the '{dataset_name}' semantic model within the '{workspace_name}' workspace has been updated to point to the '{eName}' table."
@@ -136,7 +144,7 @@ def add_table_to_direct_lake_semantic_model(
136
144
  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."
137
145
  )
138
146
 
139
- lakehouse_workspace = fabric.resolve_workspace_name(lakehouse_workspace_id)
147
+ lakehouse_workspace = resolve_workspace_name(workspace_id=lakehouse_workspace_id)
140
148
 
141
149
  with connect_semantic_model(
142
150
  dataset=dataset_id, readonly=False, workspace=workspace_id
@@ -12,6 +12,7 @@ from sempy_labs.lakehouse._shortcuts import (
12
12
  create_shortcut_onelake,
13
13
  delete_shortcut,
14
14
  reset_shortcut_cache,
15
+ list_shortcuts,
15
16
  )
16
17
 
17
18
  __all__ = [
@@ -25,4 +26,5 @@ __all__ = [
25
26
  "vacuum_lakehouse_tables",
26
27
  "reset_shortcut_cache",
27
28
  "run_table_maintenance",
29
+ "list_shortcuts",
28
30
  ]
@@ -35,7 +35,7 @@ def lakehouse_attached() -> bool:
35
35
  @log
36
36
  def optimize_lakehouse_tables(
37
37
  tables: Optional[Union[str, List[str]]] = None,
38
- lakehouse: Optional[str] = None,
38
+ lakehouse: Optional[str | UUID] = None,
39
39
  workspace: Optional[str | UUID] = None,
40
40
  ):
41
41
  """
@@ -46,8 +46,8 @@ def optimize_lakehouse_tables(
46
46
  tables : str | List[str], default=None
47
47
  The table(s) to optimize.
48
48
  Defaults to None which resovles to optimizing all tables within the lakehouse.
49
- lakehouse : str, default=None
50
- The Fabric lakehouse.
49
+ lakehouse : str | uuid.UUID, default=None
50
+ The Fabric lakehouse name or ID.
51
51
  Defaults to None which resolves to the lakehouse attached to the notebook.
52
52
  workspace : str | uuid.UUID, default=None
53
53
  The Fabric workspace name or ID used by the lakehouse.
@@ -82,7 +82,7 @@ def optimize_lakehouse_tables(
82
82
  @log
83
83
  def vacuum_lakehouse_tables(
84
84
  tables: Optional[Union[str, List[str]]] = None,
85
- lakehouse: Optional[str] = None,
85
+ lakehouse: Optional[str | UUID] = None,
86
86
  workspace: Optional[str | UUID] = None,
87
87
  retain_n_hours: Optional[int] = None,
88
88
  ):
@@ -93,8 +93,8 @@ def vacuum_lakehouse_tables(
93
93
  ----------
94
94
  tables : str | List[str] | None
95
95
  The table(s) to vacuum. If no tables are specified, all tables in the lakehouse will be optimized.
96
- lakehouse : str, default=None
97
- The Fabric lakehouse.
96
+ lakehouse : str | uuid.UUID, default=None
97
+ The Fabric lakehouse name or ID.
98
98
  Defaults to None which resolves to the lakehouse attached to the notebook.
99
99
  workspace : str | uuid.UUID, default=None
100
100
  The Fabric workspace name or ID used by the lakehouse.
@@ -107,7 +107,6 @@ def vacuum_lakehouse_tables(
107
107
  The default retention period is 168 hours (7 days) unless manually configured via table properties.
108
108
  """
109
109
 
110
- from pyspark.sql import SparkSession
111
110
  from sempy_labs.lakehouse._get_lakehouse_tables import get_lakehouse_tables
112
111
  from delta import DeltaTable
113
112