semantic-link-labs 0.12.8__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.
- semantic_link_labs-0.12.8.dist-info/METADATA +354 -0
- semantic_link_labs-0.12.8.dist-info/RECORD +243 -0
- semantic_link_labs-0.12.8.dist-info/WHEEL +5 -0
- semantic_link_labs-0.12.8.dist-info/licenses/LICENSE +21 -0
- semantic_link_labs-0.12.8.dist-info/top_level.txt +1 -0
- sempy_labs/__init__.py +606 -0
- sempy_labs/_a_lib_info.py +2 -0
- sempy_labs/_ai.py +437 -0
- sempy_labs/_authentication.py +264 -0
- sempy_labs/_bpa_translation/_model/_translations_am-ET.po +869 -0
- sempy_labs/_bpa_translation/_model/_translations_ar-AE.po +908 -0
- sempy_labs/_bpa_translation/_model/_translations_bg-BG.po +968 -0
- sempy_labs/_bpa_translation/_model/_translations_ca-ES.po +963 -0
- sempy_labs/_bpa_translation/_model/_translations_cs-CZ.po +943 -0
- sempy_labs/_bpa_translation/_model/_translations_da-DK.po +945 -0
- sempy_labs/_bpa_translation/_model/_translations_de-DE.po +988 -0
- sempy_labs/_bpa_translation/_model/_translations_el-GR.po +993 -0
- sempy_labs/_bpa_translation/_model/_translations_es-ES.po +971 -0
- sempy_labs/_bpa_translation/_model/_translations_fa-IR.po +933 -0
- sempy_labs/_bpa_translation/_model/_translations_fi-FI.po +942 -0
- sempy_labs/_bpa_translation/_model/_translations_fr-FR.po +994 -0
- sempy_labs/_bpa_translation/_model/_translations_ga-IE.po +967 -0
- sempy_labs/_bpa_translation/_model/_translations_he-IL.po +902 -0
- sempy_labs/_bpa_translation/_model/_translations_hi-IN.po +944 -0
- sempy_labs/_bpa_translation/_model/_translations_hu-HU.po +963 -0
- sempy_labs/_bpa_translation/_model/_translations_id-ID.po +946 -0
- sempy_labs/_bpa_translation/_model/_translations_is-IS.po +939 -0
- sempy_labs/_bpa_translation/_model/_translations_it-IT.po +986 -0
- sempy_labs/_bpa_translation/_model/_translations_ja-JP.po +846 -0
- sempy_labs/_bpa_translation/_model/_translations_ko-KR.po +839 -0
- sempy_labs/_bpa_translation/_model/_translations_mt-MT.po +967 -0
- sempy_labs/_bpa_translation/_model/_translations_nl-NL.po +978 -0
- sempy_labs/_bpa_translation/_model/_translations_pl-PL.po +962 -0
- sempy_labs/_bpa_translation/_model/_translations_pt-BR.po +962 -0
- sempy_labs/_bpa_translation/_model/_translations_pt-PT.po +957 -0
- sempy_labs/_bpa_translation/_model/_translations_ro-RO.po +968 -0
- sempy_labs/_bpa_translation/_model/_translations_ru-RU.po +964 -0
- sempy_labs/_bpa_translation/_model/_translations_sk-SK.po +952 -0
- sempy_labs/_bpa_translation/_model/_translations_sl-SL.po +950 -0
- sempy_labs/_bpa_translation/_model/_translations_sv-SE.po +942 -0
- sempy_labs/_bpa_translation/_model/_translations_ta-IN.po +976 -0
- sempy_labs/_bpa_translation/_model/_translations_te-IN.po +947 -0
- sempy_labs/_bpa_translation/_model/_translations_th-TH.po +924 -0
- sempy_labs/_bpa_translation/_model/_translations_tr-TR.po +953 -0
- sempy_labs/_bpa_translation/_model/_translations_uk-UA.po +961 -0
- sempy_labs/_bpa_translation/_model/_translations_zh-CN.po +804 -0
- sempy_labs/_bpa_translation/_model/_translations_zu-ZA.po +969 -0
- sempy_labs/_capacities.py +1198 -0
- sempy_labs/_capacity_migration.py +660 -0
- sempy_labs/_clear_cache.py +351 -0
- sempy_labs/_connections.py +610 -0
- sempy_labs/_dashboards.py +69 -0
- sempy_labs/_data_access_security.py +98 -0
- sempy_labs/_data_pipelines.py +162 -0
- sempy_labs/_dataflows.py +668 -0
- sempy_labs/_dax.py +501 -0
- sempy_labs/_daxformatter.py +80 -0
- sempy_labs/_delta_analyzer.py +467 -0
- sempy_labs/_delta_analyzer_history.py +301 -0
- sempy_labs/_dictionary_diffs.py +221 -0
- sempy_labs/_documentation.py +147 -0
- sempy_labs/_domains.py +51 -0
- sempy_labs/_eventhouses.py +182 -0
- sempy_labs/_external_data_shares.py +230 -0
- sempy_labs/_gateways.py +521 -0
- sempy_labs/_generate_semantic_model.py +521 -0
- sempy_labs/_get_connection_string.py +84 -0
- sempy_labs/_git.py +543 -0
- sempy_labs/_graphQL.py +90 -0
- sempy_labs/_helper_functions.py +2833 -0
- sempy_labs/_icons.py +149 -0
- sempy_labs/_job_scheduler.py +609 -0
- sempy_labs/_kql_databases.py +149 -0
- sempy_labs/_kql_querysets.py +124 -0
- sempy_labs/_kusto.py +137 -0
- sempy_labs/_labels.py +124 -0
- sempy_labs/_list_functions.py +1720 -0
- sempy_labs/_managed_private_endpoints.py +253 -0
- sempy_labs/_mirrored_databases.py +416 -0
- sempy_labs/_mirrored_warehouses.py +60 -0
- sempy_labs/_ml_experiments.py +113 -0
- sempy_labs/_model_auto_build.py +140 -0
- sempy_labs/_model_bpa.py +557 -0
- sempy_labs/_model_bpa_bulk.py +378 -0
- sempy_labs/_model_bpa_rules.py +859 -0
- sempy_labs/_model_dependencies.py +343 -0
- sempy_labs/_mounted_data_factories.py +123 -0
- sempy_labs/_notebooks.py +441 -0
- sempy_labs/_one_lake_integration.py +151 -0
- sempy_labs/_onelake.py +131 -0
- sempy_labs/_query_scale_out.py +433 -0
- sempy_labs/_refresh_semantic_model.py +435 -0
- sempy_labs/_semantic_models.py +468 -0
- sempy_labs/_spark.py +455 -0
- sempy_labs/_sql.py +241 -0
- sempy_labs/_sql_audit_settings.py +207 -0
- sempy_labs/_sql_endpoints.py +214 -0
- sempy_labs/_tags.py +201 -0
- sempy_labs/_translations.py +43 -0
- sempy_labs/_user_delegation_key.py +44 -0
- sempy_labs/_utils.py +79 -0
- sempy_labs/_vertipaq.py +1021 -0
- sempy_labs/_vpax.py +388 -0
- sempy_labs/_warehouses.py +234 -0
- sempy_labs/_workloads.py +140 -0
- sempy_labs/_workspace_identity.py +72 -0
- sempy_labs/_workspaces.py +595 -0
- sempy_labs/admin/__init__.py +170 -0
- sempy_labs/admin/_activities.py +167 -0
- sempy_labs/admin/_apps.py +145 -0
- sempy_labs/admin/_artifacts.py +65 -0
- sempy_labs/admin/_basic_functions.py +463 -0
- sempy_labs/admin/_capacities.py +508 -0
- sempy_labs/admin/_dataflows.py +45 -0
- sempy_labs/admin/_datasets.py +186 -0
- sempy_labs/admin/_domains.py +522 -0
- sempy_labs/admin/_external_data_share.py +100 -0
- sempy_labs/admin/_git.py +72 -0
- sempy_labs/admin/_items.py +265 -0
- sempy_labs/admin/_labels.py +211 -0
- sempy_labs/admin/_reports.py +241 -0
- sempy_labs/admin/_scanner.py +118 -0
- sempy_labs/admin/_shared.py +82 -0
- sempy_labs/admin/_sharing_links.py +110 -0
- sempy_labs/admin/_tags.py +131 -0
- sempy_labs/admin/_tenant.py +503 -0
- sempy_labs/admin/_tenant_keys.py +89 -0
- sempy_labs/admin/_users.py +140 -0
- sempy_labs/admin/_workspaces.py +236 -0
- sempy_labs/deployment_pipeline/__init__.py +23 -0
- sempy_labs/deployment_pipeline/_items.py +580 -0
- sempy_labs/directlake/__init__.py +57 -0
- sempy_labs/directlake/_autosync.py +58 -0
- sempy_labs/directlake/_directlake_schema_compare.py +120 -0
- sempy_labs/directlake/_directlake_schema_sync.py +161 -0
- sempy_labs/directlake/_dl_helper.py +274 -0
- sempy_labs/directlake/_generate_shared_expression.py +94 -0
- sempy_labs/directlake/_get_directlake_lakehouse.py +62 -0
- sempy_labs/directlake/_get_shared_expression.py +34 -0
- sempy_labs/directlake/_guardrails.py +96 -0
- sempy_labs/directlake/_list_directlake_model_calc_tables.py +70 -0
- sempy_labs/directlake/_show_unsupported_directlake_objects.py +90 -0
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +239 -0
- sempy_labs/directlake/_update_directlake_partition_entity.py +259 -0
- sempy_labs/directlake/_warm_cache.py +236 -0
- sempy_labs/dotnet_lib/dotnet.runtime.config.json +10 -0
- sempy_labs/environment/__init__.py +23 -0
- sempy_labs/environment/_items.py +212 -0
- sempy_labs/environment/_pubstage.py +223 -0
- sempy_labs/eventstream/__init__.py +37 -0
- sempy_labs/eventstream/_items.py +263 -0
- sempy_labs/eventstream/_topology.py +652 -0
- sempy_labs/graph/__init__.py +59 -0
- sempy_labs/graph/_groups.py +651 -0
- sempy_labs/graph/_sensitivity_labels.py +120 -0
- sempy_labs/graph/_teams.py +125 -0
- sempy_labs/graph/_user_licenses.py +96 -0
- sempy_labs/graph/_users.py +516 -0
- sempy_labs/graph_model/__init__.py +15 -0
- sempy_labs/graph_model/_background_jobs.py +63 -0
- sempy_labs/graph_model/_items.py +149 -0
- sempy_labs/lakehouse/__init__.py +67 -0
- sempy_labs/lakehouse/_blobs.py +247 -0
- sempy_labs/lakehouse/_get_lakehouse_columns.py +102 -0
- sempy_labs/lakehouse/_get_lakehouse_tables.py +274 -0
- sempy_labs/lakehouse/_helper.py +250 -0
- sempy_labs/lakehouse/_lakehouse.py +351 -0
- sempy_labs/lakehouse/_livy_sessions.py +143 -0
- sempy_labs/lakehouse/_materialized_lake_views.py +157 -0
- sempy_labs/lakehouse/_partitioning.py +165 -0
- sempy_labs/lakehouse/_schemas.py +217 -0
- sempy_labs/lakehouse/_shortcuts.py +440 -0
- sempy_labs/migration/__init__.py +35 -0
- sempy_labs/migration/_create_pqt_file.py +238 -0
- sempy_labs/migration/_direct_lake_to_import.py +105 -0
- sempy_labs/migration/_migrate_calctables_to_lakehouse.py +398 -0
- sempy_labs/migration/_migrate_calctables_to_semantic_model.py +148 -0
- sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +533 -0
- sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +172 -0
- sempy_labs/migration/_migration_validation.py +71 -0
- sempy_labs/migration/_refresh_calc_tables.py +131 -0
- sempy_labs/mirrored_azure_databricks_catalog/__init__.py +15 -0
- sempy_labs/mirrored_azure_databricks_catalog/_discover.py +213 -0
- sempy_labs/mirrored_azure_databricks_catalog/_refresh_catalog_metadata.py +45 -0
- sempy_labs/ml_model/__init__.py +23 -0
- sempy_labs/ml_model/_functions.py +427 -0
- sempy_labs/report/_BPAReportTemplate.json +232 -0
- sempy_labs/report/__init__.py +55 -0
- sempy_labs/report/_bpareporttemplate/.pbi/localSettings.json +9 -0
- sempy_labs/report/_bpareporttemplate/.platform +11 -0
- sempy_labs/report/_bpareporttemplate/StaticResources/SharedResources/BaseThemes/CY24SU06.json +710 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/page.json +11 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/1b08bce3bebabb0a27a8/visual.json +191 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/2f22ddb70c301693c165/visual.json +438 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/3b1182230aa6c600b43a/visual.json +127 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/58577ba6380c69891500/visual.json +576 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/a2a8fa5028b3b776c96c/visual.json +207 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/adfd47ef30652707b987/visual.json +506 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/b6a80ee459e716e170b1/visual.json +127 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/ce3130a721c020cc3d81/visual.json +513 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/92735ae19b31712208ad/page.json +8 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/92735ae19b31712208ad/visuals/66e60dfb526437cd78d1/visual.json +112 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/page.json +11 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/07deb8bce824e1be37d7/visual.json +513 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0b1c68838818b32ad03b/visual.json +352 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0c171de9d2683d10b930/visual.json +37 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0efa01be0510e40a645e/visual.json +542 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/6bf2f0eb830ab53cc668/visual.json +221 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/88d8141cb8500b60030c/visual.json +127 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/a753273590beed656a03/visual.json +576 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/b8fdc82cddd61ac447bc/visual.json +127 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/page.json +9 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/visuals/ce8532a7e25020271077/visual.json +38 -0
- sempy_labs/report/_bpareporttemplate/definition/pages/pages.json +10 -0
- sempy_labs/report/_bpareporttemplate/definition/report.json +176 -0
- sempy_labs/report/_bpareporttemplate/definition/version.json +4 -0
- sempy_labs/report/_bpareporttemplate/definition.pbir +14 -0
- sempy_labs/report/_download_report.py +76 -0
- sempy_labs/report/_export_report.py +257 -0
- sempy_labs/report/_generate_report.py +427 -0
- sempy_labs/report/_paginated.py +76 -0
- sempy_labs/report/_report_bpa.py +354 -0
- sempy_labs/report/_report_bpa_rules.py +115 -0
- sempy_labs/report/_report_functions.py +581 -0
- sempy_labs/report/_report_helper.py +227 -0
- sempy_labs/report/_report_list_functions.py +110 -0
- sempy_labs/report/_report_rebind.py +149 -0
- sempy_labs/report/_reportwrapper.py +3100 -0
- sempy_labs/report/_save_report.py +147 -0
- sempy_labs/snowflake_database/__init__.py +10 -0
- sempy_labs/snowflake_database/_items.py +105 -0
- sempy_labs/sql_database/__init__.py +21 -0
- sempy_labs/sql_database/_items.py +201 -0
- sempy_labs/sql_database/_mirroring.py +79 -0
- sempy_labs/theme/__init__.py +12 -0
- sempy_labs/theme/_org_themes.py +129 -0
- sempy_labs/tom/__init__.py +3 -0
- sempy_labs/tom/_model.py +5977 -0
- sempy_labs/variable_library/__init__.py +19 -0
- sempy_labs/variable_library/_functions.py +403 -0
- sempy_labs/warehouse/__init__.py +28 -0
- sempy_labs/warehouse/_items.py +234 -0
- sempy_labs/warehouse/_restore_points.py +309 -0
|
@@ -0,0 +1,140 @@
|
|
|
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
|
+
from sempy._utils._log import log
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@log
|
|
12
|
+
def list_access_entities(
|
|
13
|
+
user_email_address: str,
|
|
14
|
+
) -> pd.DataFrame:
|
|
15
|
+
"""
|
|
16
|
+
Shows a list of permission details for Fabric and Power BI items the specified user can access.
|
|
17
|
+
|
|
18
|
+
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>`_.
|
|
19
|
+
|
|
20
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
user_email_address : str
|
|
25
|
+
The user's email address.
|
|
26
|
+
|
|
27
|
+
Returns
|
|
28
|
+
-------
|
|
29
|
+
pandas.DataFrame
|
|
30
|
+
A pandas dataframe showing a list of permission details for Fabric and Power BI items the specified user can access.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
columns = {
|
|
34
|
+
"Item Id": "string",
|
|
35
|
+
"Item Name": "string",
|
|
36
|
+
"Item Type": "string",
|
|
37
|
+
"Permissions": "string",
|
|
38
|
+
"Additional Permissions": "string",
|
|
39
|
+
}
|
|
40
|
+
df = _create_dataframe(columns=columns)
|
|
41
|
+
|
|
42
|
+
responses = _base_api(
|
|
43
|
+
request=f"/v1/admin/users/{user_email_address}/access",
|
|
44
|
+
client="fabric_sp",
|
|
45
|
+
uses_pagination=True,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
rows = []
|
|
49
|
+
for r in responses:
|
|
50
|
+
for v in r.get("accessEntities", []):
|
|
51
|
+
rows.append(
|
|
52
|
+
{
|
|
53
|
+
"Item Id": v.get("id"),
|
|
54
|
+
"Item Name": v.get("displayName"),
|
|
55
|
+
"Item Type": v.get("itemAccessDetails", {}).get("type"),
|
|
56
|
+
"Permissions": v.get("itemAccessDetails", {}).get("permissions"),
|
|
57
|
+
"Additional Permissions": v.get("itemAccessDetails", {}).get(
|
|
58
|
+
"additionalPermissions"
|
|
59
|
+
),
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
if rows:
|
|
64
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
65
|
+
|
|
66
|
+
return df
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@log
|
|
70
|
+
def list_user_subscriptions(user: str | UUID) -> pd.DataFrame:
|
|
71
|
+
"""
|
|
72
|
+
Shows a list of subscriptions for the specified user. This is a preview API call.
|
|
73
|
+
|
|
74
|
+
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>`_.
|
|
75
|
+
|
|
76
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
user : str | uuid.UUID
|
|
81
|
+
The graph ID or user principal name (UPN) of the user.
|
|
82
|
+
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
pandas.DataFrame
|
|
86
|
+
A pandas dataframe showing a list of subscriptions for the specified user. This is a preview API call.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
columns = {
|
|
90
|
+
"Subscription Id": "string",
|
|
91
|
+
"Title": "string",
|
|
92
|
+
"Artifact Id": "string",
|
|
93
|
+
"Artifact Name": "string",
|
|
94
|
+
"Sub Artifact Name": "string",
|
|
95
|
+
"Artifact Type": "string",
|
|
96
|
+
"Is Enabled": "bool",
|
|
97
|
+
"Frequency": "string",
|
|
98
|
+
"Start Date": "datetime",
|
|
99
|
+
"End Date": "string",
|
|
100
|
+
"Link To Content": "bool",
|
|
101
|
+
"Preview Image": "bool",
|
|
102
|
+
"Attachment Format": "string",
|
|
103
|
+
"Users": "string",
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
df = _create_dataframe(columns=columns)
|
|
107
|
+
|
|
108
|
+
responses = _base_api(
|
|
109
|
+
request=f"/v1.0/myorg/admin/users/{user}/subscriptions",
|
|
110
|
+
client="fabric_sp",
|
|
111
|
+
uses_pagination=True,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
rows = []
|
|
115
|
+
for r in responses:
|
|
116
|
+
for v in r.get("subscriptionEntities", []):
|
|
117
|
+
rows.append(
|
|
118
|
+
{
|
|
119
|
+
"Subscription Id": v.get("id"),
|
|
120
|
+
"Title": v.get("title"),
|
|
121
|
+
"Artifact Id": v.get("artifactId"),
|
|
122
|
+
"Artifact Name": v.get("artifactDisplayName"),
|
|
123
|
+
"Sub Artifact Name": v.get("subArtifactDisplayName"),
|
|
124
|
+
"Artifact Type": v.get("artifactType"),
|
|
125
|
+
"Is Enabled": v.get("isEnabled"),
|
|
126
|
+
"Frequency": v.get("frequency"),
|
|
127
|
+
"Start Date": v.get("startDate"),
|
|
128
|
+
"End Date": v.get("endDate"),
|
|
129
|
+
"Link To Content": v.get("linkToContent"),
|
|
130
|
+
"Preview Image": v.get("previewImage"),
|
|
131
|
+
"Attachment Format": v.get("attachmentFormat"),
|
|
132
|
+
"Users": str(v.get("users")),
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
if rows:
|
|
137
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
138
|
+
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
139
|
+
|
|
140
|
+
return df
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
from sempy_labs._helper_functions import (
|
|
2
|
+
_base_api,
|
|
3
|
+
_build_url,
|
|
4
|
+
_encode_user,
|
|
5
|
+
_update_dataframe_datatypes,
|
|
6
|
+
_create_dataframe,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from uuid import UUID
|
|
10
|
+
from typing import Optional
|
|
11
|
+
from sempy_labs.admin._basic_functions import (
|
|
12
|
+
_resolve_workspace_name_and_id,
|
|
13
|
+
)
|
|
14
|
+
import sempy_labs._icons as icons
|
|
15
|
+
import pandas as pd
|
|
16
|
+
from sempy._utils._log import log
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@log
|
|
20
|
+
def add_user_to_workspace(
|
|
21
|
+
user: str | UUID,
|
|
22
|
+
role: str = "Member",
|
|
23
|
+
principal_type: str = "User",
|
|
24
|
+
workspace: Optional[str | UUID] = None,
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Grants user permissions to the specified workspace.
|
|
28
|
+
|
|
29
|
+
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>`_.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
user : str | uuid.UUID
|
|
34
|
+
The user identifier or email address. For service principals and groups you must use the user identifier.
|
|
35
|
+
role : str, default="Member"
|
|
36
|
+
The role of the user in the workspace. Options are: 'Admin', 'Contributor', 'Member', 'None', 'Viewer'.
|
|
37
|
+
principal_type : str, default="User"
|
|
38
|
+
The principal type of the user. Options are: 'App', 'Group', 'None', 'User'.
|
|
39
|
+
workspace : str | uuid.UUID, default=None
|
|
40
|
+
The Fabric workspace name or ID.
|
|
41
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
42
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
(workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
|
|
46
|
+
|
|
47
|
+
# Validation
|
|
48
|
+
role = role.capitalize()
|
|
49
|
+
roles = ["Admin", "Contributor", "Member", "None", "Viewer"]
|
|
50
|
+
if role not in roles:
|
|
51
|
+
raise ValueError(f"{icons.red_dot} Invalid role. Please choose from {roles}")
|
|
52
|
+
principal_types = ["App", "Group", "None", "User"]
|
|
53
|
+
if principal_type not in principal_types:
|
|
54
|
+
raise ValueError(
|
|
55
|
+
f"{icons.red_dot} Invalid principal type. Please choose from {principal_types}"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
user = _encode_user(user)
|
|
59
|
+
|
|
60
|
+
payload = {
|
|
61
|
+
"identifier": user, # identifier or emailAddress?
|
|
62
|
+
"principalType": principal_type,
|
|
63
|
+
"groupUserAccessRight": role,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_base_api(
|
|
67
|
+
request=f"/v1.0/myorg/admin/groups/{workspace_id}/users",
|
|
68
|
+
method="post",
|
|
69
|
+
payload=payload,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
print(
|
|
73
|
+
f"{icons.green_dot} The '{user}' user has been added with '{role.lower()}' permissions to the '{workspace_name}' workspace."
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@log
|
|
78
|
+
def delete_user_from_workspace(
|
|
79
|
+
user: str | UUID,
|
|
80
|
+
workspace: Optional[str | UUID] = None,
|
|
81
|
+
is_group: Optional[bool] = None,
|
|
82
|
+
profile_id: Optional[str] = None,
|
|
83
|
+
):
|
|
84
|
+
"""
|
|
85
|
+
Removes user permissions from the specified workspace.
|
|
86
|
+
|
|
87
|
+
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>`_.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
user : str | uuid.UUID
|
|
92
|
+
The user identifier or email address. For service principals and groups you must use the user identifier.
|
|
93
|
+
workspace : str | uuid.UUID, default=None
|
|
94
|
+
The Fabric workspace name or ID.
|
|
95
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
96
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
97
|
+
is_group : bool, default=None
|
|
98
|
+
Whether a given user is a group or not. This parameter is required when user to delete is group.
|
|
99
|
+
profile_id : str, default=None
|
|
100
|
+
The service principal profile ID to delete.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
(workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
|
|
104
|
+
|
|
105
|
+
user = _encode_user(user)
|
|
106
|
+
url = f"/v1.0/myorg/admin/groups/{workspace_id}/users/{user}"
|
|
107
|
+
|
|
108
|
+
params = {}
|
|
109
|
+
if profile_id is not None:
|
|
110
|
+
params["profileId"] = profile_id
|
|
111
|
+
if is_group is not None:
|
|
112
|
+
params["isGroup"] = is_group
|
|
113
|
+
|
|
114
|
+
url = _build_url(url, params)
|
|
115
|
+
|
|
116
|
+
_base_api(
|
|
117
|
+
request=url,
|
|
118
|
+
method="delete",
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
print(
|
|
122
|
+
f"{icons.green_dot} The '{user}' user has been removed from the '{workspace_name}' workspace."
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@log
|
|
127
|
+
def restore_deleted_workspace(workspace_id: UUID, name: str, email_address: str):
|
|
128
|
+
"""
|
|
129
|
+
Restores a deleted workspace.
|
|
130
|
+
|
|
131
|
+
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>`_.
|
|
132
|
+
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
workspace_id : uuid.UUID
|
|
136
|
+
The ID of the workspace to restore.
|
|
137
|
+
name : str
|
|
138
|
+
The name of the group to be restored
|
|
139
|
+
email_address : str
|
|
140
|
+
The email address of the owner of the group to be restored
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
payload = {
|
|
144
|
+
"name": name,
|
|
145
|
+
"emailAddress": email_address,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
_base_api(
|
|
149
|
+
request=f"/v1.0/myorg/admin/groups/{workspace_id}/restore",
|
|
150
|
+
method="post",
|
|
151
|
+
payload=payload,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
print(
|
|
155
|
+
f"{icons.green_dot} The '{workspace_id}' workspace has been restored as '{name}'."
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@log
|
|
160
|
+
def list_orphaned_workspaces(top: int = 100) -> pd.DataFrame:
|
|
161
|
+
"""
|
|
162
|
+
Shows a list of orphaned workspaces (those with no users or no admins).
|
|
163
|
+
|
|
164
|
+
This is a wrapper function for the following API:
|
|
165
|
+
`Admin - Groups ListGroupsAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-get-groups-as-admin>`_.
|
|
166
|
+
|
|
167
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
----------
|
|
171
|
+
top : int, default=100
|
|
172
|
+
The maximum number of results to return.
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
pandas.DataFrame
|
|
177
|
+
A pandas dataframe showing a list of orphaned workspaces.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
# column structure with proper data types
|
|
181
|
+
columns = {
|
|
182
|
+
"Workspace Name": "string",
|
|
183
|
+
"Workspace Id": "string",
|
|
184
|
+
"Type": "string",
|
|
185
|
+
"State": "string",
|
|
186
|
+
"Is Read Only": "bool",
|
|
187
|
+
"Is On Dedicated Capacity": "bool",
|
|
188
|
+
"Capacity Migration Status": "string",
|
|
189
|
+
"Has Workspace Level Settings": "bool",
|
|
190
|
+
"Users": "list",
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
df = _create_dataframe(columns=columns)
|
|
194
|
+
|
|
195
|
+
url = (
|
|
196
|
+
"/v1.0/myorg/admin/groups?"
|
|
197
|
+
"$expand=users&"
|
|
198
|
+
"$filter=(not users/any()) or "
|
|
199
|
+
"(not users/any(u: u/groupUserAccessRight eq Microsoft.PowerBI.ServiceContracts.Api.GroupUserAccessRight'Admin'))&"
|
|
200
|
+
f"$top={top}"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
response = _base_api(request=url, client="fabric_sp")
|
|
204
|
+
values = response.json().get("value", [])
|
|
205
|
+
df_raw = pd.json_normalize(values)
|
|
206
|
+
|
|
207
|
+
# friendly names and reorder
|
|
208
|
+
if not df_raw.empty:
|
|
209
|
+
df_raw = df_raw.rename(
|
|
210
|
+
columns={
|
|
211
|
+
"name": "Workspace Name",
|
|
212
|
+
"id": "Workspace Id",
|
|
213
|
+
"type": "Type",
|
|
214
|
+
"state": "State",
|
|
215
|
+
"isReadOnly": "Is Read Only",
|
|
216
|
+
"isOnDedicatedCapacity": "Is On Dedicated Capacity",
|
|
217
|
+
"capacityMigrationStatus": "Capacity Migration Status",
|
|
218
|
+
"hasWorkspaceLevelSettings ": "Has Workspace Level Settings", # Note the space in original
|
|
219
|
+
"users": "Users",
|
|
220
|
+
}
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
df = df_raw[list(columns.keys())].copy()
|
|
224
|
+
|
|
225
|
+
# Convert empty lists to a more readable format for Users column
|
|
226
|
+
if "Users" in df.columns:
|
|
227
|
+
df["Users"] = df["Users"].apply(
|
|
228
|
+
lambda x: x if (x is not None and len(x) > 0) else []
|
|
229
|
+
)
|
|
230
|
+
else:
|
|
231
|
+
df = _create_dataframe(columns=columns)
|
|
232
|
+
|
|
233
|
+
# proper data types
|
|
234
|
+
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
235
|
+
|
|
236
|
+
return df
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from ._items import (
|
|
2
|
+
list_deployment_pipeline_operations,
|
|
3
|
+
list_deployment_pipeline_role_assignments,
|
|
4
|
+
list_deployment_pipeline_stage_items,
|
|
5
|
+
list_deployment_pipeline_stages,
|
|
6
|
+
list_deployment_pipelines,
|
|
7
|
+
unassign_workspace_from_stage,
|
|
8
|
+
assign_workspace_to_stage,
|
|
9
|
+
delete_deployment_pipeline,
|
|
10
|
+
deploy_stage_content,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"list_deployment_pipeline_operations",
|
|
15
|
+
"list_deployment_pipeline_role_assignments",
|
|
16
|
+
"list_deployment_pipeline_stage_items",
|
|
17
|
+
"list_deployment_pipeline_stages",
|
|
18
|
+
"list_deployment_pipelines",
|
|
19
|
+
"unassign_workspace_from_stage",
|
|
20
|
+
"assign_workspace_to_stage",
|
|
21
|
+
"delete_deployment_pipeline",
|
|
22
|
+
"deploy_stage_content",
|
|
23
|
+
]
|