semantic-link-labs 0.8.9__py3-none-any.whl → 0.8.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.
- {semantic_link_labs-0.8.9.dist-info → semantic_link_labs-0.8.11.dist-info}/METADATA +5 -2
- {semantic_link_labs-0.8.9.dist-info → semantic_link_labs-0.8.11.dist-info}/RECORD +76 -75
- sempy_labs/__init__.py +14 -2
- sempy_labs/_authentication.py +31 -2
- sempy_labs/_clear_cache.py +39 -37
- sempy_labs/_connections.py +13 -13
- sempy_labs/_data_pipelines.py +20 -20
- sempy_labs/_dataflows.py +27 -28
- sempy_labs/_dax.py +41 -47
- sempy_labs/_environments.py +26 -23
- sempy_labs/_eventhouses.py +16 -15
- sempy_labs/_eventstreams.py +16 -15
- sempy_labs/_external_data_shares.py +18 -20
- sempy_labs/_gateways.py +57 -11
- sempy_labs/_generate_semantic_model.py +100 -71
- sempy_labs/_git.py +134 -67
- sempy_labs/_helper_functions.py +199 -145
- sempy_labs/_job_scheduler.py +92 -0
- sempy_labs/_kql_databases.py +16 -15
- sempy_labs/_kql_querysets.py +16 -15
- sempy_labs/_list_functions.py +281 -120
- sempy_labs/_managed_private_endpoints.py +19 -17
- sempy_labs/_mirrored_databases.py +51 -48
- sempy_labs/_mirrored_warehouses.py +5 -4
- sempy_labs/_ml_experiments.py +16 -15
- sempy_labs/_ml_models.py +15 -14
- sempy_labs/_model_bpa.py +27 -25
- sempy_labs/_model_bpa_bulk.py +3 -3
- sempy_labs/_model_dependencies.py +60 -28
- sempy_labs/_notebooks.py +73 -39
- sempy_labs/_one_lake_integration.py +23 -26
- sempy_labs/_query_scale_out.py +67 -64
- sempy_labs/_refresh_semantic_model.py +47 -42
- sempy_labs/_spark.py +33 -32
- sempy_labs/_sql.py +12 -9
- sempy_labs/_translations.py +10 -7
- sempy_labs/_vertipaq.py +34 -31
- sempy_labs/_warehouses.py +22 -21
- sempy_labs/_workspace_identity.py +11 -10
- sempy_labs/_workspaces.py +40 -33
- sempy_labs/admin/__init__.py +4 -0
- sempy_labs/admin/_basic_functions.py +44 -12
- sempy_labs/admin/_external_data_share.py +3 -3
- sempy_labs/admin/_items.py +4 -4
- sempy_labs/admin/_scanner.py +7 -5
- sempy_labs/directlake/_directlake_schema_compare.py +18 -14
- sempy_labs/directlake/_directlake_schema_sync.py +18 -12
- sempy_labs/directlake/_dl_helper.py +36 -32
- sempy_labs/directlake/_generate_shared_expression.py +10 -9
- sempy_labs/directlake/_get_directlake_lakehouse.py +16 -13
- sempy_labs/directlake/_get_shared_expression.py +4 -3
- sempy_labs/directlake/_guardrails.py +12 -6
- sempy_labs/directlake/_list_directlake_model_calc_tables.py +15 -9
- sempy_labs/directlake/_show_unsupported_directlake_objects.py +16 -10
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +35 -31
- sempy_labs/directlake/_update_directlake_partition_entity.py +34 -31
- sempy_labs/directlake/_warm_cache.py +87 -65
- sempy_labs/lakehouse/_get_lakehouse_columns.py +10 -8
- sempy_labs/lakehouse/_get_lakehouse_tables.py +10 -9
- sempy_labs/lakehouse/_lakehouse.py +17 -13
- sempy_labs/lakehouse/_shortcuts.py +42 -23
- sempy_labs/migration/_create_pqt_file.py +16 -11
- sempy_labs/migration/_refresh_calc_tables.py +16 -10
- sempy_labs/report/_download_report.py +9 -8
- sempy_labs/report/_generate_report.py +40 -44
- sempy_labs/report/_paginated.py +9 -9
- sempy_labs/report/_report_bpa.py +13 -9
- sempy_labs/report/_report_functions.py +80 -91
- sempy_labs/report/_report_helper.py +8 -4
- sempy_labs/report/_report_list_functions.py +24 -13
- sempy_labs/report/_report_rebind.py +17 -16
- sempy_labs/report/_reportwrapper.py +41 -33
- sempy_labs/tom/_model.py +117 -38
- {semantic_link_labs-0.8.9.dist-info → semantic_link_labs-0.8.11.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.8.9.dist-info → semantic_link_labs-0.8.11.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.8.9.dist-info → semantic_link_labs-0.8.11.dist-info}/top_level.txt +0 -0
sempy_labs/_connections.py
CHANGED
|
@@ -5,6 +5,7 @@ from typing import Optional
|
|
|
5
5
|
from sempy_labs._helper_functions import (
|
|
6
6
|
pagination,
|
|
7
7
|
_is_valid_uuid,
|
|
8
|
+
resolve_workspace_name_and_id,
|
|
8
9
|
)
|
|
9
10
|
from uuid import UUID
|
|
10
11
|
import sempy_labs._icons as icons
|
|
@@ -19,7 +20,7 @@ def delete_connection(connection: str | UUID):
|
|
|
19
20
|
|
|
20
21
|
Parameters
|
|
21
22
|
----------
|
|
22
|
-
connection : str | UUID
|
|
23
|
+
connection : str | uuid.UUID
|
|
23
24
|
The connection name or ID.
|
|
24
25
|
"""
|
|
25
26
|
|
|
@@ -42,9 +43,9 @@ def delete_connection_role_assignment(connection: str | UUID, role_assignment_id
|
|
|
42
43
|
|
|
43
44
|
Parameters
|
|
44
45
|
----------
|
|
45
|
-
connection : str | UUID
|
|
46
|
+
connection : str | uuid.UUID
|
|
46
47
|
The connection name or ID.
|
|
47
|
-
role_assignment_id : UUID
|
|
48
|
+
role_assignment_id : uuid.UUID
|
|
48
49
|
The role assignment ID.
|
|
49
50
|
"""
|
|
50
51
|
|
|
@@ -87,7 +88,7 @@ def list_connection_role_assignments(connection: str | UUID) -> pd.DataFrame:
|
|
|
87
88
|
|
|
88
89
|
Parameters
|
|
89
90
|
----------
|
|
90
|
-
connection : str | UUID
|
|
91
|
+
connection : str | uuid.UUID
|
|
91
92
|
The connection name or ID.
|
|
92
93
|
|
|
93
94
|
Returns
|
|
@@ -205,7 +206,7 @@ def list_connections() -> pd.DataFrame:
|
|
|
205
206
|
|
|
206
207
|
|
|
207
208
|
def list_item_connections(
|
|
208
|
-
item_name: str, item_type: str, workspace: Optional[str] = None
|
|
209
|
+
item_name: str, item_type: str, workspace: Optional[str | UUID] = None
|
|
209
210
|
) -> pd.DataFrame:
|
|
210
211
|
"""
|
|
211
212
|
Shows the list of connections that the specified item is connected to.
|
|
@@ -218,8 +219,8 @@ def list_item_connections(
|
|
|
218
219
|
The item name.
|
|
219
220
|
item_type : str
|
|
220
221
|
The `item type <https://learn.microsoft.com/rest/api/fabric/core/items/update-item?tabs=HTTP#itemtype>`_.
|
|
221
|
-
workspace : str, default=None
|
|
222
|
-
The Fabric workspace name.
|
|
222
|
+
workspace : str | uuid.UUID, default=None
|
|
223
|
+
The Fabric workspace name or ID.
|
|
223
224
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
224
225
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
225
226
|
|
|
@@ -229,11 +230,10 @@ def list_item_connections(
|
|
|
229
230
|
A pandas dataframe showing the list of connections that the specified item is connected to.
|
|
230
231
|
"""
|
|
231
232
|
|
|
232
|
-
|
|
233
|
-
workspace_id = fabric.resolve_workspace_id(workspace)
|
|
233
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
234
234
|
item_type = item_type[0].upper() + item_type[1:]
|
|
235
235
|
item_id = fabric.resolve_item_id(
|
|
236
|
-
item_name=item_name, type=item_type, workspace=
|
|
236
|
+
item_name=item_name, type=item_type, workspace=workspace_id
|
|
237
237
|
)
|
|
238
238
|
|
|
239
239
|
client = fabric.FabricRestClient()
|
|
@@ -416,7 +416,7 @@ def create_on_prem_connection(
|
|
|
416
416
|
----------
|
|
417
417
|
name : str
|
|
418
418
|
The name of the connection.
|
|
419
|
-
gateway : str | UUID
|
|
419
|
+
gateway : str | uuid.UUID
|
|
420
420
|
The name or Id of the gateway.
|
|
421
421
|
server_name : str
|
|
422
422
|
The name of the server.
|
|
@@ -485,7 +485,7 @@ def create_vnet_connection(
|
|
|
485
485
|
user_name: str,
|
|
486
486
|
password: str,
|
|
487
487
|
privacy_level: str,
|
|
488
|
-
connection_encryption:
|
|
488
|
+
connection_encryption: str = "NotEncrypted",
|
|
489
489
|
skip_test_connection: bool = False,
|
|
490
490
|
):
|
|
491
491
|
"""
|
|
@@ -497,7 +497,7 @@ def create_vnet_connection(
|
|
|
497
497
|
----------
|
|
498
498
|
name : str
|
|
499
499
|
The name of the connection.
|
|
500
|
-
gateway : str | UUID
|
|
500
|
+
gateway : str | uuid.UUID
|
|
501
501
|
The name or Id of the gateway.
|
|
502
502
|
server_name : str
|
|
503
503
|
The name of the server.
|
sempy_labs/_data_pipelines.py
CHANGED
|
@@ -9,9 +9,10 @@ from sempy_labs._helper_functions import (
|
|
|
9
9
|
_decode_b64,
|
|
10
10
|
)
|
|
11
11
|
from sempy.fabric.exceptions import FabricHTTPException
|
|
12
|
+
from uuid import UUID
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
def list_data_pipelines(workspace: Optional[str] = None) -> pd.DataFrame:
|
|
15
|
+
def list_data_pipelines(workspace: Optional[str | UUID] = None) -> pd.DataFrame:
|
|
15
16
|
"""
|
|
16
17
|
Shows the data pipelines within a workspace.
|
|
17
18
|
|
|
@@ -19,8 +20,8 @@ def list_data_pipelines(workspace: Optional[str] = None) -> pd.DataFrame:
|
|
|
19
20
|
|
|
20
21
|
Parameters
|
|
21
22
|
----------
|
|
22
|
-
workspace : str, default=None
|
|
23
|
-
The Fabric workspace name.
|
|
23
|
+
workspace : str | uuid.UUID, default=None
|
|
24
|
+
The Fabric workspace name or ID.
|
|
24
25
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
25
26
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
26
27
|
|
|
@@ -32,7 +33,7 @@ def list_data_pipelines(workspace: Optional[str] = None) -> pd.DataFrame:
|
|
|
32
33
|
|
|
33
34
|
df = pd.DataFrame(columns=["Data Pipeline Name", "Data Pipeline ID", "Description"])
|
|
34
35
|
|
|
35
|
-
(
|
|
36
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
36
37
|
|
|
37
38
|
client = fabric.FabricRestClient()
|
|
38
39
|
response = client.get(f"/v1/workspaces/{workspace_id}/dataPipelines")
|
|
@@ -54,7 +55,7 @@ def list_data_pipelines(workspace: Optional[str] = None) -> pd.DataFrame:
|
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
def create_data_pipeline(
|
|
57
|
-
name: str, description: Optional[str] = None, workspace: Optional[str] = None
|
|
58
|
+
name: str, description: Optional[str] = None, workspace: Optional[str | UUID] = None
|
|
58
59
|
):
|
|
59
60
|
"""
|
|
60
61
|
Creates a Fabric data pipeline.
|
|
@@ -67,13 +68,13 @@ def create_data_pipeline(
|
|
|
67
68
|
Name of the data pipeline.
|
|
68
69
|
description : str, default=None
|
|
69
70
|
A description of the environment.
|
|
70
|
-
workspace : str, default=None
|
|
71
|
-
The Fabric workspace name.
|
|
71
|
+
workspace : str | uuid.UUID, default=None
|
|
72
|
+
The Fabric workspace name or ID.
|
|
72
73
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
73
74
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
74
75
|
"""
|
|
75
76
|
|
|
76
|
-
(
|
|
77
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
77
78
|
|
|
78
79
|
request_body = {"displayName": name}
|
|
79
80
|
|
|
@@ -88,11 +89,11 @@ def create_data_pipeline(
|
|
|
88
89
|
lro(client, response, status_codes=[201, 202])
|
|
89
90
|
|
|
90
91
|
print(
|
|
91
|
-
f"{icons.green_dot} The '{name}' data pipeline has been created within the '{
|
|
92
|
+
f"{icons.green_dot} The '{name}' data pipeline has been created within the '{workspace_name}' workspace."
|
|
92
93
|
)
|
|
93
94
|
|
|
94
95
|
|
|
95
|
-
def delete_data_pipeline(name: str, workspace: Optional[str] = None):
|
|
96
|
+
def delete_data_pipeline(name: str, workspace: Optional[str | UUID] = None):
|
|
96
97
|
"""
|
|
97
98
|
Deletes a Fabric data pipeline.
|
|
98
99
|
|
|
@@ -102,16 +103,16 @@ def delete_data_pipeline(name: str, workspace: Optional[str] = None):
|
|
|
102
103
|
----------
|
|
103
104
|
name: str
|
|
104
105
|
Name of the data pipeline.
|
|
105
|
-
workspace : str, default=None
|
|
106
|
+
workspace : str | uuid.UUID, default=None
|
|
106
107
|
The Fabric workspace name.
|
|
107
108
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
108
109
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
109
110
|
"""
|
|
110
111
|
|
|
111
|
-
(
|
|
112
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
112
113
|
|
|
113
114
|
item_id = fabric.resolve_item_id(
|
|
114
|
-
item_name=name, type="DataPipeline", workspace=
|
|
115
|
+
item_name=name, type="DataPipeline", workspace=workspace_id
|
|
115
116
|
)
|
|
116
117
|
|
|
117
118
|
client = fabric.FabricRestClient()
|
|
@@ -121,12 +122,12 @@ def delete_data_pipeline(name: str, workspace: Optional[str] = None):
|
|
|
121
122
|
raise FabricHTTPException(response)
|
|
122
123
|
|
|
123
124
|
print(
|
|
124
|
-
f"{icons.green_dot} The '{name}' data pipeline within the '{
|
|
125
|
+
f"{icons.green_dot} The '{name}' data pipeline within the '{workspace_name}' workspace has been deleted."
|
|
125
126
|
)
|
|
126
127
|
|
|
127
128
|
|
|
128
129
|
def get_data_pipeline_definition(
|
|
129
|
-
name: str, workspace: Optional[str] = None, decode: bool = True
|
|
130
|
+
name: str, workspace: Optional[str | UUID] = None, decode: bool = True
|
|
130
131
|
) -> dict | pd.DataFrame:
|
|
131
132
|
"""
|
|
132
133
|
Obtains the definition of a data pipeline.
|
|
@@ -135,8 +136,8 @@ def get_data_pipeline_definition(
|
|
|
135
136
|
----------
|
|
136
137
|
name : str
|
|
137
138
|
The name of the data pipeline.
|
|
138
|
-
workspace : str, default=None
|
|
139
|
-
The Fabric workspace name.
|
|
139
|
+
workspace : str | uuid.UUID, default=None
|
|
140
|
+
The Fabric workspace name or ID.
|
|
140
141
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
141
142
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
142
143
|
decode : bool, default=True
|
|
@@ -150,10 +151,9 @@ def get_data_pipeline_definition(
|
|
|
150
151
|
A pandas dataframe showing the data pipelines within a workspace.
|
|
151
152
|
"""
|
|
152
153
|
|
|
153
|
-
|
|
154
|
-
workspace_id = fabric.resolve_workspace_id(workspace)
|
|
154
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
155
155
|
item_id = fabric.resolve_item_id(
|
|
156
|
-
item_name=name, type="DataPipeline", workspace=
|
|
156
|
+
item_name=name, type="DataPipeline", workspace=workspace_id
|
|
157
157
|
)
|
|
158
158
|
|
|
159
159
|
client = fabric.FabricRestClient()
|
sempy_labs/_dataflows.py
CHANGED
|
@@ -10,14 +10,14 @@ from sempy.fabric.exceptions import FabricHTTPException
|
|
|
10
10
|
from uuid import UUID
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def list_dataflows(workspace: Optional[str] = None):
|
|
13
|
+
def list_dataflows(workspace: Optional[str | UUID] = None):
|
|
14
14
|
"""
|
|
15
15
|
Shows a list of all dataflows which exist within a workspace.
|
|
16
16
|
|
|
17
17
|
Parameters
|
|
18
18
|
----------
|
|
19
|
-
workspace : str, default=None
|
|
20
|
-
The Fabric workspace name.
|
|
19
|
+
workspace : str | uuid.UUID, default=None
|
|
20
|
+
The Fabric workspace name or ID.
|
|
21
21
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
22
22
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
23
23
|
|
|
@@ -27,7 +27,7 @@ def list_dataflows(workspace: Optional[str] = None):
|
|
|
27
27
|
A pandas dataframe showing the dataflows which exist within a workspace.
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
|
-
(
|
|
30
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
31
31
|
client = fabric.PowerBIRestClient()
|
|
32
32
|
response = client.get(f"/v1.0/myorg/groups/{workspace_id}/dataflows")
|
|
33
33
|
if response.status_code != 200:
|
|
@@ -37,26 +37,27 @@ def list_dataflows(workspace: Optional[str] = None):
|
|
|
37
37
|
columns=["Dataflow Id", "Dataflow Name", "Configured By", "Users", "Generation"]
|
|
38
38
|
)
|
|
39
39
|
|
|
40
|
+
data = [] # Collect rows here
|
|
41
|
+
|
|
40
42
|
for v in response.json().get("value", []):
|
|
41
43
|
new_data = {
|
|
42
44
|
"Dataflow Id": v.get("objectId"),
|
|
43
45
|
"Dataflow Name": v.get("name"),
|
|
44
46
|
"Configured By": v.get("configuredBy"),
|
|
45
|
-
"Users":
|
|
47
|
+
"Users": v.get("users", []),
|
|
46
48
|
"Generation": v.get("generation"),
|
|
47
49
|
}
|
|
48
|
-
|
|
49
|
-
[df, pd.DataFrame(new_data, index=[0])],
|
|
50
|
-
ignore_index=True,
|
|
51
|
-
)
|
|
50
|
+
data.append(new_data)
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
if data:
|
|
53
|
+
df = pd.DataFrame(data)
|
|
54
|
+
df["Generation"] = df["Generation"].astype(int)
|
|
54
55
|
|
|
55
56
|
return df
|
|
56
57
|
|
|
57
58
|
|
|
58
59
|
def assign_workspace_to_dataflow_storage(
|
|
59
|
-
dataflow_storage_account: str, workspace: Optional[str] = None
|
|
60
|
+
dataflow_storage_account: str, workspace: Optional[str | UUID] = None
|
|
60
61
|
):
|
|
61
62
|
"""
|
|
62
63
|
Assigns a dataflow storage account to a workspace.
|
|
@@ -67,13 +68,13 @@ def assign_workspace_to_dataflow_storage(
|
|
|
67
68
|
----------
|
|
68
69
|
dataflow_storage_account : str
|
|
69
70
|
The name of the dataflow storage account.
|
|
70
|
-
workspace : str, default=None
|
|
71
|
-
The name of the workspace.
|
|
71
|
+
workspace : str | uuid.UUID, default=None
|
|
72
|
+
The name or ID of the workspace.
|
|
72
73
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
73
74
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
74
75
|
"""
|
|
75
76
|
|
|
76
|
-
(
|
|
77
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
77
78
|
|
|
78
79
|
df = list_dataflow_storage_accounts()
|
|
79
80
|
df_filt = df[df["Dataflow Storage Account Name"] == dataflow_storage_account]
|
|
@@ -95,7 +96,7 @@ def assign_workspace_to_dataflow_storage(
|
|
|
95
96
|
if response.status_code != 200:
|
|
96
97
|
raise FabricHTTPException(response)
|
|
97
98
|
print(
|
|
98
|
-
f"{icons.green_dot} The '{dataflow_storage_account}' dataflow storage account has been assigned to the '{
|
|
99
|
+
f"{icons.green_dot} The '{dataflow_storage_account}' dataflow storage account has been assigned to the '{workspace_name}' workspacce."
|
|
99
100
|
)
|
|
100
101
|
|
|
101
102
|
|
|
@@ -137,7 +138,7 @@ def list_dataflow_storage_accounts() -> pd.DataFrame:
|
|
|
137
138
|
|
|
138
139
|
|
|
139
140
|
def list_upstream_dataflows(
|
|
140
|
-
dataflow: str | UUID, workspace: Optional[str] = None
|
|
141
|
+
dataflow: str | UUID, workspace: Optional[str | UUID] = None
|
|
141
142
|
) -> pd.DataFrame:
|
|
142
143
|
"""
|
|
143
144
|
Shows a list of upstream dataflows for the specified dataflow.
|
|
@@ -146,10 +147,10 @@ def list_upstream_dataflows(
|
|
|
146
147
|
|
|
147
148
|
Parameters
|
|
148
149
|
----------
|
|
149
|
-
dataflow : str | UUID
|
|
150
|
+
dataflow : str | uuid.UUID
|
|
150
151
|
Name or UUID of the dataflow.
|
|
151
|
-
workspace : str, default=None
|
|
152
|
-
The Fabric workspace name.
|
|
152
|
+
workspace : str | uuid.UUID, default=None
|
|
153
|
+
The Fabric workspace name or ID.
|
|
153
154
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
154
155
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
155
156
|
|
|
@@ -159,10 +160,9 @@ def list_upstream_dataflows(
|
|
|
159
160
|
A pandas dataframe showing a list of upstream dataflows for the specified dataflow.
|
|
160
161
|
"""
|
|
161
162
|
|
|
162
|
-
workspace_name =
|
|
163
|
-
workspace_id = fabric.resolve_workspace_id(workspace)
|
|
163
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
164
164
|
(dataflow_name, dataflow_id) = _resolve_dataflow_name_and_id(
|
|
165
|
-
dataflow=dataflow, workspace=
|
|
165
|
+
dataflow=dataflow, workspace=workspace_id
|
|
166
166
|
)
|
|
167
167
|
client = fabric.PowerBIRestClient()
|
|
168
168
|
|
|
@@ -194,7 +194,7 @@ def list_upstream_dataflows(
|
|
|
194
194
|
tgt_workspace_id = v.get("groupId")
|
|
195
195
|
tgt_workspace_name = fabric.resolve_workspace_name(tgt_workspace_id)
|
|
196
196
|
(tgt_dataflow_name, _) = _resolve_dataflow_name_and_id(
|
|
197
|
-
dataflow=tgt_dataflow_id, workspace=
|
|
197
|
+
dataflow=tgt_dataflow_id, workspace=tgt_workspace_id
|
|
198
198
|
)
|
|
199
199
|
|
|
200
200
|
df.loc[len(df)] = {
|
|
@@ -222,13 +222,12 @@ def list_upstream_dataflows(
|
|
|
222
222
|
|
|
223
223
|
|
|
224
224
|
def _resolve_dataflow_name_and_id(
|
|
225
|
-
dataflow: str | UUID, workspace: Optional[str] = None
|
|
225
|
+
dataflow: str | UUID, workspace: Optional[str | UUID] = None
|
|
226
226
|
) -> Tuple[str, UUID]:
|
|
227
227
|
|
|
228
|
-
|
|
229
|
-
workspace = fabric.resolve_workspace_name(workspace)
|
|
228
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
230
229
|
|
|
231
|
-
dfD = list_dataflows(workspace=
|
|
230
|
+
dfD = list_dataflows(workspace=workspace_id)
|
|
232
231
|
|
|
233
232
|
if _is_valid_uuid(dataflow):
|
|
234
233
|
dfD_filt = dfD[dfD["Dataflow Id"] == dataflow]
|
|
@@ -237,7 +236,7 @@ def _resolve_dataflow_name_and_id(
|
|
|
237
236
|
|
|
238
237
|
if len(dfD_filt) == 0:
|
|
239
238
|
raise ValueError(
|
|
240
|
-
f"{icons.red_dot} The '{dataflow}' dataflow does not exist within the '{
|
|
239
|
+
f"{icons.red_dot} The '{dataflow}' dataflow does not exist within the '{workspace_name}' workspace."
|
|
241
240
|
)
|
|
242
241
|
|
|
243
242
|
dataflow_id = dfD_filt["Dataflow Id"].iloc[0]
|
sempy_labs/_dax.py
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import sempy.fabric as fabric
|
|
2
2
|
import pandas as pd
|
|
3
3
|
from sempy_labs._helper_functions import (
|
|
4
|
-
resolve_dataset_id,
|
|
5
4
|
resolve_workspace_name_and_id,
|
|
6
5
|
format_dax_object_name,
|
|
6
|
+
resolve_dataset_name_and_id,
|
|
7
7
|
)
|
|
8
8
|
from sempy_labs._model_dependencies import get_model_calc_dependencies
|
|
9
9
|
from typing import Optional, List
|
|
10
10
|
from sempy._utils._log import log
|
|
11
|
-
from
|
|
11
|
+
from uuid import UUID
|
|
12
|
+
from sempy_labs.directlake._warm_cache import _put_columns_into_memory
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
@log
|
|
15
16
|
def evaluate_dax_impersonation(
|
|
16
|
-
dataset: str,
|
|
17
|
+
dataset: str | UUID,
|
|
17
18
|
dax_query: str,
|
|
18
19
|
user_name: Optional[str] = None,
|
|
19
|
-
workspace: Optional[str] = None,
|
|
20
|
+
workspace: Optional[str | UUID] = None,
|
|
20
21
|
):
|
|
21
22
|
"""
|
|
22
23
|
Runs a DAX query against a semantic model using the `REST API <https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/execute-queries-in-group>`_.
|
|
@@ -26,14 +27,14 @@ def evaluate_dax_impersonation(
|
|
|
26
27
|
|
|
27
28
|
Parameters
|
|
28
29
|
----------
|
|
29
|
-
dataset : str
|
|
30
|
-
Name of the semantic model.
|
|
30
|
+
dataset : str | uuid.UUID
|
|
31
|
+
Name or ID of the semantic model.
|
|
31
32
|
dax_query : str
|
|
32
33
|
The DAX query.
|
|
33
34
|
user_name : str
|
|
34
35
|
The user name (i.e. hello@goodbye.com).
|
|
35
|
-
workspace : str, default=None
|
|
36
|
-
The Fabric workspace name.
|
|
36
|
+
workspace : str | uuid.UUID, default=None
|
|
37
|
+
The Fabric workspace name or ID.
|
|
37
38
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
38
39
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
39
40
|
|
|
@@ -43,8 +44,8 @@ def evaluate_dax_impersonation(
|
|
|
43
44
|
A pandas dataframe holding the result of the DAX query.
|
|
44
45
|
"""
|
|
45
46
|
|
|
46
|
-
(
|
|
47
|
-
dataset_id =
|
|
47
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
48
|
+
(dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
|
|
48
49
|
|
|
49
50
|
request_body = {
|
|
50
51
|
"queries": [{"query": dax_query}],
|
|
@@ -66,27 +67,27 @@ def evaluate_dax_impersonation(
|
|
|
66
67
|
|
|
67
68
|
@log
|
|
68
69
|
def get_dax_query_dependencies(
|
|
69
|
-
dataset: str,
|
|
70
|
+
dataset: str | UUID,
|
|
70
71
|
dax_string: str | List[str],
|
|
71
72
|
put_in_memory: bool = False,
|
|
72
73
|
show_vertipaq_stats: bool = True,
|
|
73
|
-
workspace: Optional[str] = None,
|
|
74
|
+
workspace: Optional[str | UUID] = None,
|
|
74
75
|
) -> pd.DataFrame:
|
|
75
76
|
"""
|
|
76
77
|
Obtains the columns on which a DAX query depends, including model dependencies. Shows Vertipaq statistics (i.e. Total Size, Data Size, Dictionary Size, Hierarchy Size) for easy prioritizing.
|
|
77
78
|
|
|
78
79
|
Parameters
|
|
79
80
|
----------
|
|
80
|
-
dataset : str
|
|
81
|
-
Name of the semantic model.
|
|
81
|
+
dataset : str | uuid.UUID
|
|
82
|
+
Name or ID of the semantic model.
|
|
82
83
|
dax_string : str | List[str]
|
|
83
84
|
The DAX query or list of DAX queries.
|
|
84
85
|
put_in_memory : bool, default=False
|
|
85
86
|
If True, ensures that the dependent columns are put into memory in order to give realistic Vertipaq stats (i.e. Total Size etc.).
|
|
86
87
|
show_vertipaq_stats : bool, default=True
|
|
87
88
|
If True, shows vertipaq stats (i.e. Total Size, Data Size, Dictionary Size, Hierarchy Size)
|
|
88
|
-
workspace : str, default=None
|
|
89
|
-
The Fabric workspace name.
|
|
89
|
+
workspace : str | uuid.UUID, default=None
|
|
90
|
+
The Fabric workspace name or ID.
|
|
90
91
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
91
92
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
92
93
|
|
|
@@ -96,15 +97,15 @@ def get_dax_query_dependencies(
|
|
|
96
97
|
A pandas dataframe showing the dependent columns of a given DAX query including model dependencies.
|
|
97
98
|
"""
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
101
|
+
(dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
|
|
101
102
|
|
|
102
103
|
if isinstance(dax_string, str):
|
|
103
104
|
dax_string = [dax_string]
|
|
104
105
|
|
|
105
106
|
final_df = pd.DataFrame(columns=["Object Type", "Table", "Object"])
|
|
106
107
|
|
|
107
|
-
cd = get_model_calc_dependencies(dataset=
|
|
108
|
+
cd = get_model_calc_dependencies(dataset=dataset_id, workspace=workspace_id)
|
|
108
109
|
|
|
109
110
|
for dax in dax_string:
|
|
110
111
|
# Escape quotes in dax
|
|
@@ -121,7 +122,7 @@ def get_dax_query_dependencies(
|
|
|
121
122
|
RETURN all_dependencies
|
|
122
123
|
"""
|
|
123
124
|
dep = fabric.evaluate_dax(
|
|
124
|
-
dataset=
|
|
125
|
+
dataset=dataset_id, workspace=workspace_id, dax_string=final_query
|
|
125
126
|
)
|
|
126
127
|
|
|
127
128
|
# Clean up column names and values (remove outside square brackets, underscorees in object type)
|
|
@@ -168,7 +169,7 @@ def get_dax_query_dependencies(
|
|
|
168
169
|
final_df["Full Object"] = format_dax_object_name(
|
|
169
170
|
final_df["Table Name"], final_df["Column Name"]
|
|
170
171
|
)
|
|
171
|
-
dfC = fabric.list_columns(dataset=
|
|
172
|
+
dfC = fabric.list_columns(dataset=dataset_id, workspace=workspace_id, extended=True)
|
|
172
173
|
dfC["Full Object"] = format_dax_object_name(dfC["Table Name"], dfC["Column Name"])
|
|
173
174
|
|
|
174
175
|
dfC_filtered = dfC[dfC["Full Object"].isin(final_df["Full Object"].values)][
|
|
@@ -188,32 +189,22 @@ def get_dax_query_dependencies(
|
|
|
188
189
|
not_in_memory = dfC_filtered[dfC_filtered["Is Resident"] == False]
|
|
189
190
|
|
|
190
191
|
if len(not_in_memory) > 0:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
not_in_memory[not_in_memory["Table Name"] == table_name][
|
|
198
|
-
"Full Object"
|
|
199
|
-
]
|
|
200
|
-
.astype(str)
|
|
201
|
-
.tolist()
|
|
202
|
-
)
|
|
203
|
-
dax = f"""EVALUATE TOPN(1,SUMMARIZECOLUMNS({css}))"""
|
|
204
|
-
fabric.evaluate_dax(
|
|
205
|
-
dataset=dataset, dax_string=dax, workspace=workspace
|
|
206
|
-
)
|
|
192
|
+
_put_columns_into_memory(
|
|
193
|
+
dataset=dataset,
|
|
194
|
+
workspace=workspace,
|
|
195
|
+
col_df=dfC_filtered,
|
|
196
|
+
return_dataframe=False,
|
|
197
|
+
)
|
|
207
198
|
|
|
208
199
|
# Get column stats again
|
|
209
200
|
dfC = fabric.list_columns(
|
|
210
|
-
dataset=
|
|
201
|
+
dataset=dataset_id, workspace=workspace_id, extended=True
|
|
211
202
|
)
|
|
212
203
|
dfC["Full Object"] = format_dax_object_name(
|
|
213
204
|
dfC["Table Name"], dfC["Column Name"]
|
|
214
205
|
)
|
|
215
206
|
|
|
216
|
-
dfC_filtered = dfC[dfC["Full Object"].isin(
|
|
207
|
+
dfC_filtered = dfC[dfC["Full Object"].isin(final_df["Full Object"].values)][
|
|
217
208
|
[
|
|
218
209
|
"Table Name",
|
|
219
210
|
"Column Name",
|
|
@@ -233,19 +224,19 @@ def get_dax_query_dependencies(
|
|
|
233
224
|
|
|
234
225
|
@log
|
|
235
226
|
def get_dax_query_memory_size(
|
|
236
|
-
dataset: str, dax_string: str, workspace: Optional[str] = None
|
|
227
|
+
dataset: str | UUID, dax_string: str, workspace: Optional[str | UUID] = None
|
|
237
228
|
) -> int:
|
|
238
229
|
"""
|
|
239
230
|
Obtains the total size, in bytes, used by all columns that a DAX query depends on.
|
|
240
231
|
|
|
241
232
|
Parameters
|
|
242
233
|
----------
|
|
243
|
-
dataset : str
|
|
244
|
-
Name of the semantic model.
|
|
234
|
+
dataset : str | uuid.UUID
|
|
235
|
+
Name or ID of the semantic model.
|
|
245
236
|
dax_string : str
|
|
246
237
|
The DAX query.
|
|
247
|
-
workspace : str, default=None
|
|
248
|
-
The Fabric workspace name.
|
|
238
|
+
workspace : str | uuid.UUID, default=None
|
|
239
|
+
The Fabric workspace name or ID.
|
|
249
240
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
250
241
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
251
242
|
|
|
@@ -255,11 +246,14 @@ def get_dax_query_memory_size(
|
|
|
255
246
|
The total size, in bytes, used by all columns that the DAX query depends on.
|
|
256
247
|
"""
|
|
257
248
|
|
|
258
|
-
|
|
259
|
-
|
|
249
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
250
|
+
(dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
|
|
260
251
|
|
|
261
252
|
df = get_dax_query_dependencies(
|
|
262
|
-
dataset=
|
|
253
|
+
dataset=dataset_id,
|
|
254
|
+
workspace=workspace_id,
|
|
255
|
+
dax_string=dax_string,
|
|
256
|
+
put_in_memory=True,
|
|
263
257
|
)
|
|
264
258
|
|
|
265
259
|
return df["Total Size"].sum()
|