Skip to content

Commit 507b9ff

Browse files
committed
Merge branch 'm-kovalsky/resolve_sensitivity_label_id'
2 parents af89e19 + 3d17817 commit 507b9ff

File tree

5 files changed

+261
-3
lines changed

5 files changed

+261
-3
lines changed

src/sempy_labs/admin/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@
9898
remove_all_sharing_links,
9999
remove_sharing_links,
100100
)
101+
from ._labels import (
102+
bulk_set_labels,
103+
bulk_remove_labels,
104+
)
101105

102106
__all__ = [
103107
"list_items",
@@ -161,4 +165,6 @@
161165
"rotate_tenant_key",
162166
"remove_all_sharing_links",
163167
"remove_sharing_links",
168+
"bulk_set_labels",
169+
"bulk_remove_labels",
164170
]

src/sempy_labs/admin/_items.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
from typing import Optional, Tuple
33
from uuid import UUID
44
import sempy_labs._icons as icons
5-
from ._basic_functions import (
5+
from sempy_labs.admin._basic_functions import (
66
_resolve_workspace_name_and_id,
77
)
8-
from ._capacities import (
8+
from sempy_labs.admin._capacities import (
99
_resolve_capacity_name_and_id,
1010
)
11-
from .._helper_functions import (
11+
from sempy_labs._helper_functions import (
1212
_is_valid_uuid,
1313
_build_url,
1414
_base_api,

src/sempy_labs/admin/_labels.py

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
from typing import Literal, List
2+
from uuid import UUID
3+
import sempy_labs._icons as icons
4+
from sempy_labs.admin._basic_functions import (
5+
_resolve_workspace_name_and_id,
6+
)
7+
from sempy_labs.admin._items import (
8+
list_items,
9+
)
10+
from sempy_labs._helper_functions import (
11+
_is_valid_uuid,
12+
_base_api,
13+
)
14+
from sempy._utils._log import log
15+
16+
17+
@log
18+
def bulk_set_labels(
19+
items: List[dict],
20+
label_id: UUID,
21+
assignment_method: Literal["Standard", "Priviledged"] = "Standard",
22+
):
23+
"""
24+
Sets sensitivity labels on Fabric items.
25+
26+
Note: Please use the sempy_labs.graph.resolve_sensitivity_label_id function to retrieve label IDs.
27+
28+
This is a wrapper function for the following API: `Labels - Bulk Set Labels <https://learn.microsoft.com/rest/api/fabric/admin/labels/bulk-set-labels>`_.
29+
30+
Parameters
31+
----------
32+
items : List[dict]
33+
A list of dictionaries containing the item details.
34+
35+
Example 1:
36+
items = [
37+
{
38+
"id": "fe472f5e-636e-4c10-a1c6-7e9edc0b542a",
39+
"type": "Dashboard"
40+
},
41+
{
42+
"id": "fe472f5e-636e-4c10-a1c6-7e9edc0b542c",
43+
"type": "Report"
44+
},
45+
{
46+
"id": "fe472f5e-636e-4c10-a1c6-7e9edc0b542e",
47+
"type": "SemanticModel"
48+
},
49+
]
50+
51+
Example 2:
52+
items = [
53+
{
54+
"id": "Dashboard 1",
55+
"type": "Dashboard",
56+
"workspace": "Sales Workspace"
57+
},
58+
{
59+
"id": "Sales Report",
60+
"type": "Report",
61+
"workspace": "Sales Workspace"
62+
},
63+
{
64+
"id": "KPI Model",
65+
"type": "SemanticModel",
66+
"workspace": "Workspace 2"
67+
},
68+
]
69+
70+
label_id : uuid.UUID
71+
The label ID, which must be in the user's label policy.
72+
assignment_method : Literal["Standard", "Priviledged"], default="Standard"
73+
Specifies whether the assigned label was set by an automated process or manually. Additional tenant setting property types may be added over time.
74+
"""
75+
76+
if assignment_method not in ["Standard", "Priviledged"]:
77+
raise ValueError("assignment_method must be either 'Standard' or 'Priviledged'")
78+
79+
payload = {"items": []}
80+
df = list_items()
81+
82+
for i in items:
83+
item = i.get("item")
84+
type = i.get("type")
85+
workspace = i.get("workspace")
86+
if _is_valid_uuid(item):
87+
payload["items"].append(
88+
{
89+
"id": item,
90+
"type": type,
91+
}
92+
)
93+
else:
94+
workspace_id = _resolve_workspace_name_and_id(workspace)[1]
95+
df_filtered = df[
96+
(df["Item Name"] == item)
97+
& (df["Type"] == type)
98+
& (df["Workspace Id"] == workspace_id)
99+
]
100+
if df_filtered.empty:
101+
raise ValueError(
102+
f"The item '{item}' of type '{type}' does not exist in workspace '{workspace}'."
103+
)
104+
else:
105+
payload["items"].append(
106+
{
107+
"id": df_filtered["Item Id"].iloc[0],
108+
"type": type,
109+
}
110+
)
111+
112+
payload["labelId"] = label_id
113+
payload["assignmentMethod"] = assignment_method
114+
115+
_base_api(request="/v1/admin/items/bulkSetLabels", method="post", payload=payload)
116+
117+
print(
118+
f"{icons.green_dot} Labels have been successfully set on the specified items."
119+
)
120+
121+
122+
@log
123+
def bulk_remove_labels(
124+
items: List[dict],
125+
):
126+
"""
127+
Removes sensitivity labels from Fabric items.
128+
129+
This is a wrapper function for the following API: `Labels - Bulk Remove Labels <https://learn.microsoft.com/rest/api/fabric/admin/labels/bulk-remove-labels>`_.
130+
131+
Parameters
132+
----------
133+
items : List[dict]
134+
A list of dictionaries containing the item details.
135+
136+
Example 1:
137+
items = [
138+
{
139+
"id": "fe472f5e-636e-4c10-a1c6-7e9edc0b542a",
140+
"type": "Dashboard"
141+
},
142+
{
143+
"id": "fe472f5e-636e-4c10-a1c6-7e9edc0b542c",
144+
"type": "Report"
145+
},
146+
{
147+
"id": "fe472f5e-636e-4c10-a1c6-7e9edc0b542e",
148+
"type": "SemanticModel"
149+
},
150+
]
151+
152+
Example 2:
153+
items = [
154+
{
155+
"id": "Dashboard 1",
156+
"type": "Dashboard",
157+
"workspace": "Sales Workspace"
158+
},
159+
{
160+
"id": "Sales Report",
161+
"type": "Report",
162+
"workspace": "Sales Workspace"
163+
},
164+
{
165+
"id": "KPI Model",
166+
"type": "SemanticModel",
167+
"workspace": "Workspace 2"
168+
},
169+
]
170+
"""
171+
172+
payload = {"items": []}
173+
df = list_items()
174+
175+
for i in items:
176+
item = i.get("item")
177+
type = i.get("type")
178+
workspace = i.get("workspace")
179+
if _is_valid_uuid(item):
180+
payload["items"].append(
181+
{
182+
"id": item,
183+
"type": type,
184+
}
185+
)
186+
else:
187+
workspace_id = _resolve_workspace_name_and_id(workspace)[1]
188+
df_filtered = df[
189+
(df["Item Name"] == item)
190+
& (df["Type"] == type)
191+
& (df["Workspace Id"] == workspace_id)
192+
]
193+
if df_filtered.empty:
194+
raise ValueError(
195+
f"The item '{item}' of type '{type}' does not exist in workspace '{workspace}'."
196+
)
197+
else:
198+
payload["items"].append(
199+
{
200+
"id": df_filtered["Item Id"].iloc[0],
201+
"type": type,
202+
}
203+
)
204+
205+
_base_api(
206+
request="/v1/admin/items/bulkRemoveLabels", method="post", payload=payload
207+
)
208+
209+
print(
210+
f"{icons.green_dot} Labels have been successfully removed from the specified items."
211+
)

src/sempy_labs/graph/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
)
2525
from ._sensitivity_labels import (
2626
list_sensitivity_labels,
27+
resolve_sensitivity_label_id,
2728
)
2829

2930
__all__ = [
@@ -46,4 +47,5 @@
4647
"update_user",
4748
"update_group",
4849
"list_sensitivity_labels",
50+
"resolve_sensitivity_label_id",
4951
]

src/sempy_labs/graph/_sensitivity_labels.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
_base_api,
66
_create_dataframe,
77
_update_dataframe_datatypes,
8+
_is_valid_uuid,
89
)
910
from sempy._utils._log import log
1011

@@ -79,3 +80,41 @@ def list_sensitivity_labels(user: Optional[str | UUID] = None) -> pd.DataFrame:
7980
_update_dataframe_datatypes(dataframe=df, column_map=columns)
8081

8182
return df
83+
84+
85+
@log
86+
def resolve_sensitivity_label_id(
87+
label: str | UUID, user: Optional[str | UUID] = None
88+
) -> UUID | None:
89+
"""
90+
Resolve a sensitivity label name or ID to its corresponding sensitivity label ID.
91+
92+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
93+
94+
Parameters
95+
----------
96+
label : str | uuid.UUID
97+
The name or ID of the sensitivity label.
98+
user : str | uuid.UUID, default=None
99+
The user ID or user principal name.
100+
101+
Returns
102+
-------
103+
uuid.UUID | None
104+
The ID of the sensitivity label if found, otherwise None.
105+
"""
106+
107+
if _is_valid_uuid(label):
108+
return str(label)
109+
110+
df = list_sensitivity_labels(user=user)
111+
112+
if df.empty:
113+
return None
114+
115+
# Try to find the label by name
116+
label_row = df[df["Sensitivity Label Name"] == label]
117+
if not label_row.empty:
118+
return label_row["Sensitivity Label Id"].iloc[0]
119+
120+
return None

0 commit comments

Comments
 (0)