semantic-link-labs 0.9.4__py3-none-any.whl → 0.9.5__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.9.4.dist-info → semantic_link_labs-0.9.5.dist-info}/METADATA +18 -2
- {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.5.dist-info}/RECORD +49 -43
- sempy_labs/__init__.py +18 -3
- sempy_labs/_capacities.py +22 -127
- sempy_labs/_capacity_migration.py +8 -7
- sempy_labs/_dashboards.py +60 -0
- sempy_labs/_data_pipelines.py +5 -31
- sempy_labs/_environments.py +20 -48
- sempy_labs/_eventhouses.py +22 -52
- sempy_labs/_eventstreams.py +16 -34
- sempy_labs/_gateways.py +4 -4
- sempy_labs/_generate_semantic_model.py +0 -1
- sempy_labs/_git.py +90 -1
- sempy_labs/_graphQL.py +3 -20
- sempy_labs/_helper_functions.py +171 -43
- sempy_labs/_kql_databases.py +19 -34
- sempy_labs/_kql_querysets.py +15 -32
- sempy_labs/_list_functions.py +12 -155
- sempy_labs/_mirrored_databases.py +14 -48
- sempy_labs/_ml_experiments.py +5 -30
- sempy_labs/_ml_models.py +4 -28
- sempy_labs/_model_bpa.py +2 -0
- sempy_labs/_mounted_data_factories.py +119 -0
- sempy_labs/_notebooks.py +16 -26
- sempy_labs/_sql.py +7 -6
- sempy_labs/_utils.py +42 -0
- sempy_labs/_vertipaq.py +17 -2
- sempy_labs/_warehouses.py +5 -17
- sempy_labs/_workloads.py +23 -9
- sempy_labs/_workspaces.py +13 -5
- sempy_labs/admin/__init__.py +21 -1
- sempy_labs/admin/_apps.py +1 -1
- sempy_labs/admin/_artifacts.py +62 -0
- sempy_labs/admin/_basic_functions.py +0 -52
- sempy_labs/admin/_capacities.py +61 -0
- sempy_labs/admin/_reports.py +74 -0
- sempy_labs/admin/_shared.py +4 -2
- sempy_labs/admin/_users.py +133 -0
- sempy_labs/admin/_workspaces.py +148 -0
- sempy_labs/directlake/_update_directlake_partition_entity.py +9 -1
- sempy_labs/lakehouse/__init__.py +2 -0
- sempy_labs/lakehouse/_lakehouse.py +6 -7
- sempy_labs/lakehouse/_shortcuts.py +192 -53
- sempy_labs/report/_generate_report.py +9 -17
- sempy_labs/report/_report_bpa.py +12 -19
- sempy_labs/tom/_model.py +34 -16
- {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.5.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.5.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
from sempy_labs._helper_functions import (
|
|
2
|
+
_base_api,
|
|
3
|
+
_create_dataframe,
|
|
4
|
+
_update_dataframe_datatypes,
|
|
5
|
+
)
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def list_access_entities(
|
|
11
|
+
user_email_address: str,
|
|
12
|
+
) -> pd.DataFrame:
|
|
13
|
+
"""
|
|
14
|
+
Shows a list of permission details for Fabric and Power BI items the specified user can access.
|
|
15
|
+
|
|
16
|
+
This is a wrapper function for the following API: `Users - List Access Entities <https://learn.microsoft.com/rest/api/fabric/admin/users/list-access-entities>`_.
|
|
17
|
+
|
|
18
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
user_email_address : str
|
|
23
|
+
The user's email address.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
pandas.DataFrame
|
|
28
|
+
A pandas dataframe showing a list of permission details for Fabric and Power BI items the specified user can access.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
columns = {
|
|
32
|
+
"Item Id": "string",
|
|
33
|
+
"Item Name": "string",
|
|
34
|
+
"Item Type": "string",
|
|
35
|
+
"Permissions": "string",
|
|
36
|
+
"Additional Permissions": "string",
|
|
37
|
+
}
|
|
38
|
+
df = _create_dataframe(columns=columns)
|
|
39
|
+
|
|
40
|
+
responses = _base_api(
|
|
41
|
+
request=f"/v1/admin/users/{user_email_address}/access",
|
|
42
|
+
client="fabric_sp",
|
|
43
|
+
uses_pagination=True,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
for r in responses:
|
|
47
|
+
for v in r.get("accessEntities", []):
|
|
48
|
+
new_data = {
|
|
49
|
+
"Item Id": v.get("id"),
|
|
50
|
+
"Item Name": v.get("displayName"),
|
|
51
|
+
"Item Type": v.get("itemAccessDetails", {}).get("type"),
|
|
52
|
+
"Permissions": v.get("itemAccessDetails", {}).get("permissions"),
|
|
53
|
+
"Additional Permissions": v.get("itemAccessDetails", {}).get(
|
|
54
|
+
"additionalPermissions"
|
|
55
|
+
),
|
|
56
|
+
}
|
|
57
|
+
df = pd.concat([df, pd.DataFrame([new_data])], ignore_index=True)
|
|
58
|
+
|
|
59
|
+
return df
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def list_user_subscriptions(user: str | UUID) -> pd.DataFrame:
|
|
63
|
+
"""
|
|
64
|
+
Shows a list of subscriptions for the specified user. This is a preview API call.
|
|
65
|
+
|
|
66
|
+
This is a wrapper function for the following API: `Admin - Users GetUserSubscriptionsAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/users-get-user-subscriptions-as-admin>`_.
|
|
67
|
+
|
|
68
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
user : str | uuid.UUID
|
|
73
|
+
The graph ID or user principal name (UPN) of the user.
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
pandas.DataFrame
|
|
78
|
+
A pandas dataframe showing a list of subscriptions for the specified user. This is a preview API call.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
columns = {
|
|
82
|
+
"Subscription Id": "string",
|
|
83
|
+
"Title": "string",
|
|
84
|
+
"Artifact Id": "string",
|
|
85
|
+
"Artifact Name": "string",
|
|
86
|
+
"Sub Artifact Name": "string",
|
|
87
|
+
"Artifact Type": "string",
|
|
88
|
+
"Is Enabled": "bool",
|
|
89
|
+
"Frequency": "string",
|
|
90
|
+
"Start Date": "datetime",
|
|
91
|
+
"End Date": "string",
|
|
92
|
+
"Link To Content": "bool",
|
|
93
|
+
"Preview Image": "bool",
|
|
94
|
+
"Attachment Format": "string",
|
|
95
|
+
"Users": "string",
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
df = _create_dataframe(columns=columns)
|
|
99
|
+
|
|
100
|
+
responses = _base_api(
|
|
101
|
+
request=f"/v1.0/myorg/admin/users/{user}/subscriptions",
|
|
102
|
+
client="fabric_sp",
|
|
103
|
+
uses_pagination=True,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
rows = []
|
|
107
|
+
for r in responses:
|
|
108
|
+
for v in r.get("subscriptionEntities", []):
|
|
109
|
+
rows.append(
|
|
110
|
+
{
|
|
111
|
+
"Subscription Id": v.get("id"),
|
|
112
|
+
"Title": v.get("title"),
|
|
113
|
+
"Artifact Id": v.get("artifactId"),
|
|
114
|
+
"Artifact Name": v.get("artifactDisplayName"),
|
|
115
|
+
"Sub Artifact Name": v.get("subArtifactDisplayName"),
|
|
116
|
+
"Artifact Type": v.get("artifactType"),
|
|
117
|
+
"Is Enabled": v.get("isEnabled"),
|
|
118
|
+
"Frequency": v.get("frequency"),
|
|
119
|
+
"Start Date": v.get("startDate"),
|
|
120
|
+
"End Date": v.get("endDate"),
|
|
121
|
+
"Link To Content": v.get("linkToContent"),
|
|
122
|
+
"Preview Image": v.get("previewImage"),
|
|
123
|
+
"Attachment Format": v.get("attachmentFormat"),
|
|
124
|
+
"Users": str(v.get("users")),
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
if rows:
|
|
129
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
130
|
+
|
|
131
|
+
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
132
|
+
|
|
133
|
+
return df
|
|
@@ -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
|
+
)
|
|
@@ -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
|
-
|
|
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."
|
sempy_labs/lakehouse/__init__.py
CHANGED
|
@@ -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
|
|