Skip to content

Commit 4e28c4a

Browse files
committed
Merge branch 'm-kovalsky/externaldatashares'
2 parents 840cd22 + 9ae9b38 commit 4e28c4a

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed

src/sempy_labs/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
from sempy_labs._external_data_shares import (
2+
list_external_data_shares_in_item,
3+
create_external_data_share,
4+
revoke_external_data_share,
5+
)
16
from sempy_labs._ml_models import (
27
list_ml_models,
38
create_ml_model,
@@ -361,4 +366,7 @@
361366
"list_sql_endpoints",
362367
"list_datamarts",
363368
"get_data_pipeline_definition",
369+
"list_external_data_shares_in_item",
370+
"create_external_data_share",
371+
"revoke_external_data_share",
364372
]
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import sempy.fabric as fabric
2+
from uuid import UUID
3+
import pandas as pd
4+
from typing import Optional, List
5+
import sempy_labs._icons as icons
6+
from sempy_labs._helper_functions import (
7+
resolve_workspace_name_and_id,
8+
pagination,
9+
)
10+
from sempy.fabric.exceptions import FabricHTTPException
11+
12+
13+
def create_external_data_share(
14+
item_name: str,
15+
item_type: str,
16+
paths: str | List[str],
17+
recipient: str,
18+
workspace: Optional[str] = None,
19+
):
20+
"""
21+
Creates an external data share for a given path or list of paths in the specified item.
22+
23+
Parameters
24+
----------
25+
item_name : str
26+
The item name.
27+
item_type : str
28+
The `item type <https://learn.microsoft.com/rest/api/fabric/core/items/list-items?tabs=HTTP#itemtype>`_.
29+
paths : str | List[str]
30+
The path or list of paths that are to be externally shared. Currently, only a single path is supported.
31+
recipient : str
32+
The email address of the recipient.
33+
workspace : str, default=None
34+
The Fabric workspace name.
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+
# https://learn.microsoft.com/en-us/rest/api/fabric/core/external-data-shares/create-external-data-share?tabs=HTTP
40+
41+
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
42+
item_id = fabric.resolve_item_id(
43+
item_name=item_name, type=item_type, workspace=workspace
44+
)
45+
46+
if isinstance(paths, str):
47+
paths = [paths]
48+
49+
payload = {"paths": paths, "recipient": {"userPrincipalName": recipient}}
50+
51+
client = fabric.FabricRestClient()
52+
response = client.post(
53+
f"/v1/workspaces/{workspace_id}/items/{item_id}/externalDataShares",
54+
json=payload,
55+
)
56+
57+
if response.status_code != 201:
58+
raise FabricHTTPException(response)
59+
60+
print(
61+
f"{icons.green_dot} An external data share was created for the '{item_name}' {item_type} within the '{workspace}' workspace for the {paths} paths."
62+
)
63+
64+
65+
def revoke_external_data_share(
66+
external_data_share_id: UUID,
67+
item_name: str,
68+
item_type: str,
69+
workspace: Optional[str] = None,
70+
):
71+
"""
72+
Revokes the specified external data share. Note: This action cannot be undone.
73+
74+
Parameters
75+
----------
76+
external_data_share_id : UUID
77+
The external data share ID.
78+
item_name : str
79+
The item name.
80+
item_type : str
81+
The `item type <https://learn.microsoft.com/rest/api/fabric/core/items/list-items?tabs=HTTP#itemtype>`_.
82+
workspace : str, default=None
83+
The Fabric workspace name.
84+
Defaults to None which resolves to the workspace of the attached lakehouse
85+
or if no lakehouse attached, resolves to the workspace of the notebook.
86+
"""
87+
88+
# https://learn.microsoft.com/en-us/rest/api/fabric/core/external-data-shares/revoke-external-data-share?tabs=HTTP
89+
90+
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
91+
item_id = fabric.resolve_item_id(
92+
item_name=item_name, type=item_type, workspace=workspace
93+
)
94+
95+
client = fabric.FabricRestClient()
96+
response = client.post(
97+
f"/v1/workspaces/{workspace_id}/items/{item_id}/externalDataShares/{external_data_share_id}/revoke"
98+
)
99+
100+
if response.status_code != 200:
101+
raise FabricHTTPException(response)
102+
103+
print(
104+
f"{icons.green_dot} The '{external_data_share_id}' external data share for the '{item_name}' {item_type} within the '{workspace}' workspace has been revoked."
105+
)
106+
107+
108+
def list_external_data_shares_in_item(
109+
item_name: str, item_type: str, workspace: Optional[str] = None
110+
) -> pd.DataFrame:
111+
"""
112+
Returns a list of the external data shares that exist for the specified item.
113+
114+
Parameters
115+
----------
116+
item_name : str
117+
The item name.
118+
item_type : str
119+
The `item type <https://learn.microsoft.com/rest/api/fabric/core/items/list-items?tabs=HTTP#itemtype>`_.
120+
workspace : str, default=None
121+
The Fabric workspace name.
122+
Defaults to None which resolves to the workspace of the attached lakehouse
123+
or if no lakehouse attached, resolves to the workspace of the notebook.
124+
125+
Returns
126+
-------
127+
pandas.DataFrame
128+
A pandas dataframe showing a list of the external data shares that exist for the specified item.
129+
"""
130+
131+
# https://learn.microsoft.com/en-us/rest/api/fabric/core/external-data-shares/list-external-data-shares-in-item?tabs=HTTP
132+
133+
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
134+
item_id = fabric.resolve_item_id(
135+
item_name=item_name, type=item_type, workspace=workspace
136+
)
137+
138+
client = fabric.FabricRestClient()
139+
response = client.get(
140+
f"/v1/workspaces/{workspace_id}/items/{item_id}/externalDataShares"
141+
)
142+
143+
if response.status_code != 200:
144+
raise FabricHTTPException(response)
145+
146+
df = pd.DataFrame(
147+
columns=[
148+
"External Data Share Id",
149+
"Paths",
150+
"Creator Principal Id",
151+
"Creater Principal Type",
152+
"Recipient User Principal Name",
153+
"Status",
154+
"Expiration Time UTC",
155+
"Workspace Id",
156+
"Item Id",
157+
"Item Name",
158+
"Item Type",
159+
"Invitation URL",
160+
]
161+
)
162+
163+
responses = pagination(client, response)
164+
dfs = []
165+
166+
for r in responses:
167+
for i in r.get("value", []):
168+
item_id = i.get("itemId")
169+
new_data = {
170+
"External Data Share Id": i.get("id"),
171+
"Paths": [i.get("paths")],
172+
"Creator Principal Id": i.get("creatorPrincipal", {}).get("id"),
173+
"Creator Principal Type": i.get("creatorPrincipal", {}).get("type"),
174+
"Recipient User Principal Name": i.get("recipient", {}).get("userPrincipalName"),
175+
"Status": i.get("status"),
176+
"Expiration Time UTC": i.get("expriationTimeUtc"),
177+
"Workspace Id": i.get("workspaceId"),
178+
"Item Id": item_id,
179+
"Item Name": item_name,
180+
"Item Type": item_type,
181+
"Invitation URL": i.get("invitationUrl"),
182+
}
183+
dfs.append(pd.DataFrame(new_data, index=[0]))
184+
df = pd.concat(dfs, ignore_index=True)
185+
186+
return df

0 commit comments

Comments
 (0)