semantic-link-labs 0.8.0__py3-none-any.whl → 0.8.1__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.0.dist-info → semantic_link_labs-0.8.1.dist-info}/METADATA +39 -7
- {semantic_link_labs-0.8.0.dist-info → semantic_link_labs-0.8.1.dist-info}/RECORD +47 -37
- sempy_labs/__init__.py +70 -51
- sempy_labs/_ai.py +0 -2
- sempy_labs/_capacity_migration.py +1 -2
- sempy_labs/_data_pipelines.py +118 -0
- sempy_labs/_documentation.py +144 -0
- sempy_labs/_eventhouses.py +118 -0
- sempy_labs/_eventstreams.py +118 -0
- sempy_labs/_generate_semantic_model.py +3 -3
- sempy_labs/_git.py +3 -3
- sempy_labs/_helper_functions.py +116 -26
- sempy_labs/_icons.py +21 -0
- sempy_labs/_kql_databases.py +134 -0
- sempy_labs/_kql_querysets.py +124 -0
- sempy_labs/_list_functions.py +12 -425
- sempy_labs/_mirrored_warehouses.py +50 -0
- sempy_labs/_ml_experiments.py +122 -0
- sempy_labs/_ml_models.py +120 -0
- sempy_labs/_model_auto_build.py +0 -4
- sempy_labs/_model_bpa.py +9 -11
- sempy_labs/_model_bpa_bulk.py +8 -7
- sempy_labs/_model_dependencies.py +26 -18
- sempy_labs/_notebooks.py +5 -16
- sempy_labs/_query_scale_out.py +2 -2
- sempy_labs/_refresh_semantic_model.py +7 -19
- sempy_labs/_spark.py +10 -10
- sempy_labs/_vertipaq.py +16 -18
- sempy_labs/_warehouses.py +132 -0
- sempy_labs/_workspaces.py +0 -3
- sempy_labs/admin/_basic_functions.py +92 -10
- sempy_labs/admin/_domains.py +1 -1
- sempy_labs/directlake/_directlake_schema_sync.py +1 -1
- sempy_labs/directlake/_dl_helper.py +32 -16
- sempy_labs/directlake/_guardrails.py +7 -7
- sempy_labs/directlake/_update_directlake_partition_entity.py +1 -1
- sempy_labs/directlake/_warm_cache.py +1 -1
- sempy_labs/lakehouse/_get_lakehouse_tables.py +3 -3
- sempy_labs/lakehouse/_lakehouse.py +3 -2
- sempy_labs/migration/_migrate_calctables_to_lakehouse.py +5 -0
- sempy_labs/report/_generate_report.py +1 -1
- sempy_labs/report/_report_bpa.py +13 -3
- sempy_labs/report/_reportwrapper.py +14 -16
- sempy_labs/tom/_model.py +261 -24
- {semantic_link_labs-0.8.0.dist-info → semantic_link_labs-0.8.1.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.8.0.dist-info → semantic_link_labs-0.8.1.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.8.0.dist-info → semantic_link_labs-0.8.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import sempy.fabric as fabric
|
|
2
|
+
from sempy_labs._helper_functions import (
|
|
3
|
+
resolve_workspace_name_and_id,
|
|
4
|
+
pagination,
|
|
5
|
+
lro,
|
|
6
|
+
)
|
|
7
|
+
import pandas as pd
|
|
8
|
+
from typing import Optional
|
|
9
|
+
import sempy_labs._icons as icons
|
|
10
|
+
from sempy.fabric.exceptions import FabricHTTPException
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def create_warehouse(
|
|
14
|
+
warehouse: str, description: Optional[str] = None, workspace: Optional[str] = None
|
|
15
|
+
):
|
|
16
|
+
"""
|
|
17
|
+
Creates a Fabric warehouse.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
warehouse: str
|
|
22
|
+
Name of the warehouse.
|
|
23
|
+
description : str, default=None
|
|
24
|
+
A description of the warehouse.
|
|
25
|
+
workspace : str, default=None
|
|
26
|
+
The Fabric workspace name.
|
|
27
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
28
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
32
|
+
|
|
33
|
+
request_body = {"displayName": warehouse}
|
|
34
|
+
|
|
35
|
+
if description:
|
|
36
|
+
request_body["description"] = description
|
|
37
|
+
|
|
38
|
+
client = fabric.FabricRestClient()
|
|
39
|
+
response = client.post(
|
|
40
|
+
f"/v1/workspaces/{workspace_id}/warehouses/", json=request_body
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
lro(client, response, status_codes=[201, 202])
|
|
44
|
+
|
|
45
|
+
print(
|
|
46
|
+
f"{icons.green_dot} The '{warehouse}' warehouse has been created within the '{workspace}' workspace."
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def list_warehouses(workspace: Optional[str] = None) -> pd.DataFrame:
|
|
51
|
+
"""
|
|
52
|
+
Shows the warehouses within a workspace.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
workspace : str, default=None
|
|
57
|
+
The Fabric workspace name.
|
|
58
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
59
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
60
|
+
|
|
61
|
+
Returns
|
|
62
|
+
-------
|
|
63
|
+
pandas.DataFrame
|
|
64
|
+
A pandas dataframe showing the warehouses within a workspace.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
df = pd.DataFrame(
|
|
68
|
+
columns=[
|
|
69
|
+
"Warehouse Name",
|
|
70
|
+
"Warehouse Id",
|
|
71
|
+
"Description",
|
|
72
|
+
"Connection Info",
|
|
73
|
+
"Created Date",
|
|
74
|
+
"Last Updated Time",
|
|
75
|
+
]
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
79
|
+
|
|
80
|
+
client = fabric.FabricRestClient()
|
|
81
|
+
response = client.get(f"/v1/workspaces/{workspace_id}/warehouses")
|
|
82
|
+
if response.status_code != 200:
|
|
83
|
+
raise FabricHTTPException(response)
|
|
84
|
+
|
|
85
|
+
responses = pagination(client, response)
|
|
86
|
+
|
|
87
|
+
for r in responses:
|
|
88
|
+
for v in r.get("value", []):
|
|
89
|
+
prop = v.get("properties", {})
|
|
90
|
+
|
|
91
|
+
new_data = {
|
|
92
|
+
"Warehouse Name": v.get("displayName"),
|
|
93
|
+
"Warehouse Id": v.get("id"),
|
|
94
|
+
"Description": v.get("description"),
|
|
95
|
+
"Connection Info": prop.get("connectionInfo"),
|
|
96
|
+
"Created Date": prop.get("createdDate"),
|
|
97
|
+
"Last Updated Time": prop.get("lastUpdatedTime"),
|
|
98
|
+
}
|
|
99
|
+
df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
|
|
100
|
+
|
|
101
|
+
return df
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def delete_warehouse(name: str, workspace: Optional[str] = None):
|
|
105
|
+
"""
|
|
106
|
+
Deletes a Fabric warehouse.
|
|
107
|
+
|
|
108
|
+
Parameters
|
|
109
|
+
----------
|
|
110
|
+
name: str
|
|
111
|
+
Name of the warehouse.
|
|
112
|
+
workspace : str, default=None
|
|
113
|
+
The Fabric workspace name.
|
|
114
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
115
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
119
|
+
|
|
120
|
+
item_id = fabric.resolve_item_id(
|
|
121
|
+
item_name=name, type="Warehouse", workspace=workspace
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
client = fabric.FabricRestClient()
|
|
125
|
+
response = client.delete(f"/v1/workspaces/{workspace_id}/warehouses/{item_id}")
|
|
126
|
+
|
|
127
|
+
if response.status_code != 200:
|
|
128
|
+
raise FabricHTTPException(response)
|
|
129
|
+
|
|
130
|
+
print(
|
|
131
|
+
f"{icons.green_dot} The '{name}' warehouse within the '{workspace}' workspace has been deleted."
|
|
132
|
+
)
|
sempy_labs/_workspaces.py
CHANGED
|
@@ -22,9 +22,6 @@ def delete_user_from_workspace(email_address: str, workspace: Optional[str] = No
|
|
|
22
22
|
The name of the workspace.
|
|
23
23
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
24
24
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
25
|
-
|
|
26
|
-
Returns
|
|
27
|
-
-------
|
|
28
25
|
"""
|
|
29
26
|
|
|
30
27
|
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
@@ -3,7 +3,10 @@ from typing import Optional, List, Union
|
|
|
3
3
|
from uuid import UUID
|
|
4
4
|
import sempy_labs._icons as icons
|
|
5
5
|
from sempy.fabric.exceptions import FabricHTTPException
|
|
6
|
-
from sempy_labs._helper_functions import
|
|
6
|
+
from sempy_labs._helper_functions import (
|
|
7
|
+
resolve_workspace_name_and_id,
|
|
8
|
+
pagination,
|
|
9
|
+
)
|
|
7
10
|
import datetime
|
|
8
11
|
import numpy as np
|
|
9
12
|
import pandas as pd
|
|
@@ -387,7 +390,7 @@ def revoke_external_data_share(
|
|
|
387
390
|
|
|
388
391
|
|
|
389
392
|
def list_capacities_delegated_tenant_settings(
|
|
390
|
-
return_dataframe:
|
|
393
|
+
return_dataframe: bool = True,
|
|
391
394
|
) -> Optional[pd.DataFrame | dict]:
|
|
392
395
|
"""
|
|
393
396
|
Returns list of tenant setting overrides that override at the capacities.
|
|
@@ -477,11 +480,11 @@ def list_capacities_delegated_tenant_settings(
|
|
|
477
480
|
|
|
478
481
|
|
|
479
482
|
def scan_workspaces(
|
|
480
|
-
data_source_details:
|
|
481
|
-
dataset_schema:
|
|
482
|
-
dataset_expressions:
|
|
483
|
-
lineage:
|
|
484
|
-
artifact_users:
|
|
483
|
+
data_source_details: bool = False,
|
|
484
|
+
dataset_schema: bool = False,
|
|
485
|
+
dataset_expressions: bool = False,
|
|
486
|
+
lineage: bool = False,
|
|
487
|
+
artifact_users: bool = False,
|
|
485
488
|
workspace: Optional[str | List[str]] = None,
|
|
486
489
|
) -> dict:
|
|
487
490
|
|
|
@@ -519,6 +522,16 @@ def scan_workspaces(
|
|
|
519
522
|
|
|
520
523
|
|
|
521
524
|
def list_datasets() -> pd.DataFrame:
|
|
525
|
+
"""
|
|
526
|
+
Shows a list of datasets for the organization.
|
|
527
|
+
|
|
528
|
+
Returns
|
|
529
|
+
-------
|
|
530
|
+
pandas.DataFrame
|
|
531
|
+
A pandas dataframe showing a list of datasets for the organization.
|
|
532
|
+
"""
|
|
533
|
+
|
|
534
|
+
# https://learn.microsoft.com/en-us/rest/api/power-bi/admin/datasets-get-datasets-as-admin
|
|
522
535
|
|
|
523
536
|
df = pd.DataFrame(
|
|
524
537
|
columns=[
|
|
@@ -544,8 +557,7 @@ def list_datasets() -> pd.DataFrame:
|
|
|
544
557
|
]
|
|
545
558
|
)
|
|
546
559
|
|
|
547
|
-
client = fabric.
|
|
548
|
-
|
|
560
|
+
client = fabric.PowerBIRestClient()
|
|
549
561
|
response = client.get("/v1.0/myorg/admin/datasets")
|
|
550
562
|
|
|
551
563
|
if response.status_code != 200:
|
|
@@ -600,6 +612,25 @@ def list_datasets() -> pd.DataFrame:
|
|
|
600
612
|
def list_item_access_details(
|
|
601
613
|
item_name: str, type: str, workspace: Optional[str] = None
|
|
602
614
|
) -> pd.DataFrame:
|
|
615
|
+
"""
|
|
616
|
+
Returns a list of users (including groups and service principals) and lists their workspace roles.
|
|
617
|
+
|
|
618
|
+
Parameters
|
|
619
|
+
----------
|
|
620
|
+
item_name : str
|
|
621
|
+
Name of the Fabric item.
|
|
622
|
+
type : str
|
|
623
|
+
Type of Fabric item.
|
|
624
|
+
workspace : str, default=None
|
|
625
|
+
The Fabric workspace name.
|
|
626
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
627
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
628
|
+
|
|
629
|
+
Returns
|
|
630
|
+
-------
|
|
631
|
+
pandas.DataFrame
|
|
632
|
+
A pandas dataframe showing a list of users (including groups and service principals) and lists their workspace roles.
|
|
633
|
+
"""
|
|
603
634
|
|
|
604
635
|
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/items/list-item-access-details?tabs=HTTP
|
|
605
636
|
|
|
@@ -652,6 +683,19 @@ def list_item_access_details(
|
|
|
652
683
|
def list_access_entities(
|
|
653
684
|
user_email_address: str,
|
|
654
685
|
) -> pd.DataFrame:
|
|
686
|
+
"""
|
|
687
|
+
Shows a list of permission details for Fabric and PowerBI items the specified user can access.
|
|
688
|
+
|
|
689
|
+
Parameters
|
|
690
|
+
----------
|
|
691
|
+
user_email_address : str
|
|
692
|
+
The user's email address.
|
|
693
|
+
|
|
694
|
+
Returns
|
|
695
|
+
-------
|
|
696
|
+
pandas.DataFrame
|
|
697
|
+
A pandas dataframe showing a list of permission details for Fabric and PowerBI items the specified user can access.
|
|
698
|
+
"""
|
|
655
699
|
|
|
656
700
|
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/users/list-access-entities?tabs=HTTP
|
|
657
701
|
|
|
@@ -691,8 +735,23 @@ def list_access_entities(
|
|
|
691
735
|
def list_workspace_access_details(
|
|
692
736
|
workspace: Optional[Union[str, UUID]] = None
|
|
693
737
|
) -> pd.DataFrame:
|
|
738
|
+
"""
|
|
739
|
+
Shows a list of users (including groups and Service Principals) that have access to the specified workspace.
|
|
694
740
|
|
|
695
|
-
|
|
741
|
+
Parameters
|
|
742
|
+
----------
|
|
743
|
+
workspace : str, default=None
|
|
744
|
+
The Fabric workspace name.
|
|
745
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
746
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
747
|
+
|
|
748
|
+
Returns
|
|
749
|
+
-------
|
|
750
|
+
pandas.DataFrame
|
|
751
|
+
A pandas dataframe showing a list of users (including groups and Service Principals) that have access to the specified workspace.
|
|
752
|
+
"""
|
|
753
|
+
|
|
754
|
+
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/workspaces/list-workspace-access-details?tabs=HTTP
|
|
696
755
|
|
|
697
756
|
workspace_name = fabric.resolve_workspace_name(workspace)
|
|
698
757
|
workspace_id = fabric.resolve_workspace_id(workspace_name)
|
|
@@ -732,6 +791,29 @@ def list_items(
|
|
|
732
791
|
state: Optional[str] = None,
|
|
733
792
|
type: Optional[str] = None,
|
|
734
793
|
) -> pd.DataFrame:
|
|
794
|
+
"""
|
|
795
|
+
Shows a list of active Fabric and PowerBI items.
|
|
796
|
+
|
|
797
|
+
Parameters
|
|
798
|
+
----------
|
|
799
|
+
capacity_name : str, default=None
|
|
800
|
+
The capacity name.
|
|
801
|
+
workspace : str, default=None
|
|
802
|
+
The Fabric workspace name.
|
|
803
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
804
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
805
|
+
state : str, default=None
|
|
806
|
+
The item state.
|
|
807
|
+
type : str, default=None
|
|
808
|
+
The item type.
|
|
809
|
+
|
|
810
|
+
Returns
|
|
811
|
+
-------
|
|
812
|
+
pandas.DataFrame
|
|
813
|
+
A pandas dataframe showing a list of active Fabric and Power BI items.
|
|
814
|
+
"""
|
|
815
|
+
|
|
816
|
+
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/items/list-items?tabs=HTTP
|
|
735
817
|
|
|
736
818
|
url = "/v1/admin/items?"
|
|
737
819
|
|
sempy_labs/admin/_domains.py
CHANGED
|
@@ -30,7 +30,7 @@ def resolve_domain_id(domain_name: str) -> UUID:
|
|
|
30
30
|
return dfL_filt["Domain ID"].iloc[0]
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
def list_domains(non_empty_only:
|
|
33
|
+
def list_domains(non_empty_only: bool = False) -> pd.DataFrame:
|
|
34
34
|
"""
|
|
35
35
|
Shows a list of domains.
|
|
36
36
|
|
|
@@ -5,7 +5,11 @@ from typing import Optional, List, Union, Tuple
|
|
|
5
5
|
from uuid import UUID
|
|
6
6
|
import sempy_labs._icons as icons
|
|
7
7
|
from sempy._utils._log import log
|
|
8
|
-
from sempy_labs._helper_functions import
|
|
8
|
+
from sempy_labs._helper_functions import (
|
|
9
|
+
retry,
|
|
10
|
+
resolve_dataset_id,
|
|
11
|
+
resolve_lakehouse_name,
|
|
12
|
+
)
|
|
9
13
|
|
|
10
14
|
|
|
11
15
|
def check_fallback_reason(
|
|
@@ -28,16 +32,17 @@ def check_fallback_reason(
|
|
|
28
32
|
pandas.DataFrame
|
|
29
33
|
The tables in the semantic model and their fallback reason.
|
|
30
34
|
"""
|
|
35
|
+
from sempy_labs.tom import connect_semantic_model
|
|
31
36
|
|
|
32
37
|
workspace = fabric.resolve_workspace_name(workspace)
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
with connect_semantic_model(
|
|
40
|
+
dataset=dataset, workspace=workspace, readonly=True
|
|
41
|
+
) as tom:
|
|
42
|
+
if not tom.is_direct_lake():
|
|
43
|
+
raise ValueError(
|
|
44
|
+
f"{icons.red_dot} The '{dataset}' semantic model is not in Direct Lake. This function is only applicable to Direct Lake semantic models."
|
|
45
|
+
)
|
|
41
46
|
|
|
42
47
|
df = fabric.evaluate_dax(
|
|
43
48
|
dataset=dataset,
|
|
@@ -73,8 +78,9 @@ def generate_direct_lake_semantic_model(
|
|
|
73
78
|
workspace: Optional[str] = None,
|
|
74
79
|
lakehouse: Optional[str] = None,
|
|
75
80
|
lakehouse_workspace: Optional[str] = None,
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
schema: str = "dbo",
|
|
82
|
+
overwrite: bool = False,
|
|
83
|
+
refresh: bool = True,
|
|
78
84
|
):
|
|
79
85
|
"""
|
|
80
86
|
Dynamically generates a Direct Lake semantic model based on tables in a Fabric lakehouse.
|
|
@@ -96,23 +102,32 @@ def generate_direct_lake_semantic_model(
|
|
|
96
102
|
The Fabric workspace in which the lakehouse resides.
|
|
97
103
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
98
104
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
105
|
+
schema : str, default="dbo"
|
|
106
|
+
The schema used for the lakehouse.
|
|
99
107
|
overwrite : bool, default=False
|
|
100
108
|
If set to True, overwrites the existing semantic model if it already exists.
|
|
101
109
|
refresh: bool, default=True
|
|
102
110
|
If True, refreshes the newly created semantic model after it is created.
|
|
103
|
-
|
|
104
|
-
Returns
|
|
105
|
-
-------
|
|
106
111
|
"""
|
|
107
112
|
|
|
108
113
|
from sempy_labs.lakehouse import get_lakehouse_tables, get_lakehouse_columns
|
|
109
|
-
from sempy_labs import create_blank_semantic_model, refresh_semantic_model
|
|
110
|
-
from sempy_labs.tom import connect_semantic_model
|
|
111
114
|
from sempy_labs.directlake import get_shared_expression
|
|
115
|
+
from sempy_labs.tom import connect_semantic_model
|
|
116
|
+
from sempy_labs._generate_semantic_model import create_blank_semantic_model
|
|
117
|
+
from sempy_labs._refresh_semantic_model import refresh_semantic_model
|
|
112
118
|
|
|
113
119
|
if isinstance(lakehouse_tables, str):
|
|
114
120
|
lakehouse_tables = [lakehouse_tables]
|
|
115
121
|
|
|
122
|
+
workspace = fabric.resolve_workspace_name(workspace)
|
|
123
|
+
if lakehouse_workspace is None:
|
|
124
|
+
lakehouse_workspace = workspace
|
|
125
|
+
if lakehouse is None:
|
|
126
|
+
lakehouse_id = fabric.get_lakehouse_id()
|
|
127
|
+
lakehouse_workspace_id = fabric.get_workspace_id()
|
|
128
|
+
lakehouse_workspace = fabric.resolve_workspace_name(lakehouse_workspace_id)
|
|
129
|
+
lakehouse = resolve_lakehouse_name(lakehouse_id, lakehouse_workspace)
|
|
130
|
+
|
|
116
131
|
dfLT = get_lakehouse_tables(lakehouse=lakehouse, workspace=lakehouse_workspace)
|
|
117
132
|
|
|
118
133
|
# Validate lakehouse tables
|
|
@@ -158,7 +173,7 @@ def generate_direct_lake_semantic_model(
|
|
|
158
173
|
|
|
159
174
|
for t in lakehouse_tables:
|
|
160
175
|
tom.add_table(name=t)
|
|
161
|
-
tom.add_entity_partition(table_name=t, entity_name=t)
|
|
176
|
+
tom.add_entity_partition(table_name=t, entity_name=t, schema_name=schema)
|
|
162
177
|
dfLC_filt = dfLC[dfLC["Table Name"] == t]
|
|
163
178
|
for i, r in dfLC_filt.iterrows():
|
|
164
179
|
lakeCName = r["Column Name"]
|
|
@@ -212,6 +227,7 @@ def get_direct_lake_source(
|
|
|
212
227
|
response = client.post(
|
|
213
228
|
"metadata/relations/upstream?apiVersion=3", json=request_body
|
|
214
229
|
)
|
|
230
|
+
|
|
215
231
|
artifacts = response.json().get("artifacts", [])
|
|
216
232
|
sql_id, sql_object_name, sql_workspace_id, artifact_type = None, None, None, None
|
|
217
233
|
|
|
@@ -7,10 +7,7 @@ import sempy_labs._icons as icons
|
|
|
7
7
|
def get_direct_lake_guardrails() -> pd.DataFrame:
|
|
8
8
|
"""
|
|
9
9
|
Shows the guardrails for when Direct Lake semantic models will fallback to Direct Query
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Parameters
|
|
13
|
-
----------
|
|
10
|
+
based on Microsoft's `online documentation <https://learn.microsoft.com/power-bi/enterprise/directlake-overview>`_.
|
|
14
11
|
|
|
15
12
|
Returns
|
|
16
13
|
-------
|
|
@@ -21,9 +18,12 @@ def get_direct_lake_guardrails() -> pd.DataFrame:
|
|
|
21
18
|
url = "https://learn.microsoft.com/power-bi/enterprise/directlake-overview"
|
|
22
19
|
|
|
23
20
|
tables = pd.read_html(url)
|
|
24
|
-
df
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
for df in tables:
|
|
22
|
+
first_column_name = df.columns[0]
|
|
23
|
+
if first_column_name.startswith("Fabric"):
|
|
24
|
+
df[first_column_name] = df[first_column_name].str.split("/")
|
|
25
|
+
df = df.explode(first_column_name, ignore_index=True)
|
|
26
|
+
break
|
|
27
27
|
|
|
28
28
|
return df
|
|
29
29
|
|
|
@@ -24,9 +24,9 @@ from sempy.fabric.exceptions import FabricHTTPException
|
|
|
24
24
|
def get_lakehouse_tables(
|
|
25
25
|
lakehouse: Optional[str] = None,
|
|
26
26
|
workspace: Optional[str] = None,
|
|
27
|
-
extended:
|
|
28
|
-
count_rows:
|
|
29
|
-
export:
|
|
27
|
+
extended: bool = False,
|
|
28
|
+
count_rows: bool = False,
|
|
29
|
+
export: bool = False,
|
|
30
30
|
) -> pd.DataFrame:
|
|
31
31
|
"""
|
|
32
32
|
Shows the tables of a lakehouse and their respective properties. Option to include additional properties relevant to Direct Lake guardrails.
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import sempy.fabric as fabric
|
|
2
2
|
from tqdm.auto import tqdm
|
|
3
|
-
from pyspark.sql import SparkSession
|
|
4
3
|
from sempy_labs._helper_functions import resolve_lakehouse_name
|
|
5
4
|
from typing import List, Optional, Union
|
|
6
|
-
import sempy_labs._icons as icons
|
|
7
5
|
from sempy._utils._log import log
|
|
8
6
|
|
|
9
7
|
|
|
@@ -16,6 +14,7 @@ def lakehouse_attached() -> bool:
|
|
|
16
14
|
bool
|
|
17
15
|
Returns True if a lakehouse is attached to the notebook.
|
|
18
16
|
"""
|
|
17
|
+
from pyspark.sql import SparkSession
|
|
19
18
|
|
|
20
19
|
spark = SparkSession.builder.getOrCreate()
|
|
21
20
|
lakeId = spark.conf.get("trident.lakehouse.id")
|
|
@@ -49,6 +48,7 @@ def optimize_lakehouse_tables(
|
|
|
49
48
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
50
49
|
"""
|
|
51
50
|
|
|
51
|
+
from pyspark.sql import SparkSession
|
|
52
52
|
from sempy_labs.lakehouse._get_lakehouse_tables import get_lakehouse_tables
|
|
53
53
|
from delta import DeltaTable
|
|
54
54
|
|
|
@@ -107,6 +107,7 @@ 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
|
|
110
111
|
from sempy_labs.lakehouse._get_lakehouse_tables import get_lakehouse_tables
|
|
111
112
|
from delta import DeltaTable
|
|
112
113
|
|
|
@@ -8,6 +8,7 @@ from sempy_labs._helper_functions import (
|
|
|
8
8
|
resolve_lakehouse_id,
|
|
9
9
|
create_abfss_path,
|
|
10
10
|
retry,
|
|
11
|
+
generate_guid,
|
|
11
12
|
)
|
|
12
13
|
from sempy_labs.tom import connect_semantic_model
|
|
13
14
|
from pyspark.sql import SparkSession
|
|
@@ -343,6 +344,8 @@ def migrate_field_parameters(
|
|
|
343
344
|
|
|
344
345
|
tbl = TOM.Table()
|
|
345
346
|
tbl.Name = tName
|
|
347
|
+
tbl.LineageTag = generate_guid()
|
|
348
|
+
tbl.SourceLineageTag = generate_guid()
|
|
346
349
|
tbl.Partitions.Add(par)
|
|
347
350
|
|
|
348
351
|
columns = ["Value1", "Value2", "Value3"]
|
|
@@ -352,6 +355,8 @@ def migrate_field_parameters(
|
|
|
352
355
|
col.Name = colName
|
|
353
356
|
col.SourceColumn = "[" + colName + "]"
|
|
354
357
|
col.DataType = TOM.DataType.String
|
|
358
|
+
col.LineageTag = generate_guid()
|
|
359
|
+
col.SourceLineageTag = generate_guid()
|
|
355
360
|
|
|
356
361
|
tbl.Columns.Add(col)
|
|
357
362
|
|
|
@@ -313,7 +313,7 @@ def _create_report(
|
|
|
313
313
|
dataset: str,
|
|
314
314
|
dataset_workspace: Optional[str] = None,
|
|
315
315
|
report_workspace: Optional[str] = None,
|
|
316
|
-
update_if_exists:
|
|
316
|
+
update_if_exists: bool = False,
|
|
317
317
|
):
|
|
318
318
|
|
|
319
319
|
from sempy_labs.report import report_rebind
|
sempy_labs/report/_report_bpa.py
CHANGED
|
@@ -14,6 +14,7 @@ from sempy_labs._helper_functions import (
|
|
|
14
14
|
from sempy_labs.lakehouse import get_lakehouse_tables, lakehouse_attached
|
|
15
15
|
import sempy_labs._icons as icons
|
|
16
16
|
from IPython.display import display, HTML
|
|
17
|
+
import sempy_labs.report._report_helper as helper
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
@log
|
|
@@ -22,8 +23,8 @@ def run_report_bpa(
|
|
|
22
23
|
rules: Optional[pd.DataFrame] = None,
|
|
23
24
|
workspace: Optional[str] = None,
|
|
24
25
|
# language: Optional[str] = None,
|
|
25
|
-
export:
|
|
26
|
-
return_dataframe:
|
|
26
|
+
export: bool = False,
|
|
27
|
+
return_dataframe: bool = False,
|
|
27
28
|
):
|
|
28
29
|
"""
|
|
29
30
|
Displays an HTML visualization of the results of the Best Practice Analyzer scan for a report.
|
|
@@ -50,6 +51,7 @@ def run_report_bpa(
|
|
|
50
51
|
"""
|
|
51
52
|
|
|
52
53
|
rpt = ReportWrapper(report=report, workspace=workspace)
|
|
54
|
+
|
|
53
55
|
dfCV = rpt.list_custom_visuals()
|
|
54
56
|
dfP = rpt.list_pages()
|
|
55
57
|
dfRF = rpt.list_report_filters()
|
|
@@ -57,6 +59,12 @@ def run_report_bpa(
|
|
|
57
59
|
dfRF["Table Name"], dfRF["Object Name"]
|
|
58
60
|
)
|
|
59
61
|
dfPF = rpt.list_page_filters()
|
|
62
|
+
# Convert back to dataframe
|
|
63
|
+
# if isinstance(dfPF, pd.io.formats.style.Styler):
|
|
64
|
+
# dfPF = dfPF.data
|
|
65
|
+
# if isinstance(dfP, pd.io.formats.style.Styler):
|
|
66
|
+
# dfP = dfP.data
|
|
67
|
+
|
|
60
68
|
dfPF["Filter Object"] = (
|
|
61
69
|
dfPF["Page Display Name"]
|
|
62
70
|
+ " : "
|
|
@@ -134,7 +142,9 @@ def run_report_bpa(
|
|
|
134
142
|
df_output["Severity"] = row["Severity"]
|
|
135
143
|
df_output["Description"] = row["Description"]
|
|
136
144
|
df_output["URL"] = row["URL"]
|
|
137
|
-
df_output["Report URL"] =
|
|
145
|
+
df_output["Report URL"] = helper.get_web_url(
|
|
146
|
+
report=report, workspace=workspace
|
|
147
|
+
)
|
|
138
148
|
|
|
139
149
|
page_mapping_dict = dfP.set_index("Page Display Name")["Page URL"].to_dict()
|
|
140
150
|
|