|
| 1 | +from typing import Optional |
| 2 | +from uuid import UUID |
| 3 | +import pandas as pd |
| 4 | +from sempy_labs._helper_functions import ( |
| 5 | + _create_dataframe, |
| 6 | + _base_api, |
| 7 | + resolve_workspace_id, |
| 8 | + resolve_item_id, |
| 9 | +) |
| 10 | +from sempy._utils._log import log |
| 11 | + |
| 12 | + |
| 13 | +@log |
| 14 | +def list_data_access_roles( |
| 15 | + item: str | UUID, type: str, workspace: Optional[str | UUID] = None |
| 16 | +) -> pd.DataFrame: |
| 17 | + """ |
| 18 | + Returns a list of OneLake roles. |
| 19 | +
|
| 20 | + This is a wrapper function for the following API: `OneLake Data Access Security - List Data Access Roles <https://learn.microsoft.com/rest/api/fabric/core/onelake-data-access-security/list-data-access-roles>`_. |
| 21 | +
|
| 22 | + Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples). |
| 23 | +
|
| 24 | + Parameters |
| 25 | + ---------- |
| 26 | + item : str | uuid.UUID |
| 27 | + The name or ID of the item. |
| 28 | + type : str |
| 29 | + The type of the item. |
| 30 | + workspace : str | uuid.UUID, default=None |
| 31 | + The Fabric workspace name or ID. |
| 32 | + Defaults to None which resolves to the workspace of the attached lakehouse |
| 33 | + or if no lakehouse attached, resolves to the workspace of the notebook. |
| 34 | +
|
| 35 | + Returns |
| 36 | + ------- |
| 37 | + pandas.DataFrame |
| 38 | + A pandas dataframe showing a list of OneLake roles. |
| 39 | + """ |
| 40 | + |
| 41 | + columns = { |
| 42 | + "Role Name": "string", |
| 43 | + "Effect": "string", |
| 44 | + "Attribute Name": "string", |
| 45 | + "Attribute Values": "string", |
| 46 | + "Item Access": "string", |
| 47 | + "Source Path": "string", |
| 48 | + } |
| 49 | + |
| 50 | + df = _create_dataframe(columns=columns) |
| 51 | + |
| 52 | + workspace_id = resolve_workspace_id(workspace) |
| 53 | + item_id = resolve_item_id(item=item, type=type, workspace=workspace_id) |
| 54 | + |
| 55 | + responses = _base_api( |
| 56 | + request=f"/v1/workspaces/{workspace_id}/items/{item_id}/dataAccessRoles", |
| 57 | + uses_pagination=True, |
| 58 | + client="fabric_sp", |
| 59 | + ) |
| 60 | + |
| 61 | + rows = [] |
| 62 | + for r in responses: |
| 63 | + for role in r.get("value", []): |
| 64 | + name = role.get("name") |
| 65 | + |
| 66 | + # Loop through members first (since they are crucial) |
| 67 | + members = role.get("members", {}).get("fabricItemMembers", []) |
| 68 | + if not members: |
| 69 | + members = [{}] # if no members exist, still create at least one row |
| 70 | + |
| 71 | + for member in members: |
| 72 | + item_access = member.get("itemAccess", []) |
| 73 | + source_path = member.get("sourcePath") |
| 74 | + |
| 75 | + # Loop through decision rules |
| 76 | + for rule in role.get("decisionRules", []): |
| 77 | + effect = rule.get("effect") |
| 78 | + |
| 79 | + # Loop through permissions |
| 80 | + for perm in rule.get("permission", []): |
| 81 | + attr_name = perm.get("attributeName") |
| 82 | + attr_values = perm.get("attributeValueIncludedIn", []) |
| 83 | + |
| 84 | + rows.append( |
| 85 | + { |
| 86 | + "Role Name": name, |
| 87 | + "Effect": effect, |
| 88 | + "Attribute Name": attr_name, |
| 89 | + "Attribute Values": ", ".join(attr_values), |
| 90 | + "Item Access": ", ".join(item_access), |
| 91 | + "Source Path": source_path, |
| 92 | + } |
| 93 | + ) |
| 94 | + |
| 95 | + if rows: |
| 96 | + df = pd.DataFrame(rows, columns=list(columns.keys())) |
| 97 | + |
| 98 | + return df |
0 commit comments