semantic-link-labs 0.8.3__py3-none-any.whl → 0.8.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.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/METADATA +38 -8
- {semantic_link_labs-0.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/RECORD +109 -104
- {semantic_link_labs-0.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/WHEEL +1 -1
- sempy_labs/__init__.py +53 -1
- sempy_labs/_bpa_translation/_model/_translations_am-ET.po +24 -5
- sempy_labs/_bpa_translation/_model/_translations_ar-AE.po +28 -4
- sempy_labs/_bpa_translation/_model/_translations_bg-BG.po +34 -4
- sempy_labs/_bpa_translation/_model/_translations_ca-ES.po +33 -4
- sempy_labs/_bpa_translation/_model/_translations_cs-CZ.po +31 -4
- sempy_labs/_bpa_translation/_model/_translations_da-DK.po +31 -4
- sempy_labs/_bpa_translation/_model/_translations_de-DE.po +34 -4
- sempy_labs/_bpa_translation/_model/_translations_el-GR.po +36 -4
- sempy_labs/_bpa_translation/_model/_translations_es-ES.po +90 -58
- sempy_labs/_bpa_translation/_model/_translations_fa-IR.po +31 -5
- sempy_labs/_bpa_translation/_model/_translations_fi-FI.po +31 -4
- sempy_labs/_bpa_translation/_model/_translations_fr-FR.po +34 -4
- sempy_labs/_bpa_translation/_model/_translations_ga-IE.po +34 -4
- sempy_labs/_bpa_translation/_model/_translations_he-IL.po +28 -4
- sempy_labs/_bpa_translation/_model/_translations_hi-IN.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_hu-HU.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_id-ID.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_is-IS.po +31 -4
- sempy_labs/_bpa_translation/_model/_translations_it-IT.po +34 -4
- sempy_labs/_bpa_translation/_model/_translations_ja-JP.po +24 -4
- sempy_labs/_bpa_translation/_model/_translations_ko-KR.po +72 -56
- sempy_labs/_bpa_translation/_model/_translations_mt-MT.po +34 -4
- sempy_labs/_bpa_translation/_model/_translations_nl-NL.po +34 -4
- sempy_labs/_bpa_translation/_model/_translations_pl-PL.po +95 -71
- sempy_labs/_bpa_translation/_model/_translations_pt-BR.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_pt-PT.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_ro-RO.po +33 -4
- sempy_labs/_bpa_translation/_model/_translations_ru-RU.po +34 -4
- sempy_labs/_bpa_translation/_model/_translations_sk-SK.po +31 -4
- sempy_labs/_bpa_translation/_model/_translations_sl-SL.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_sv-SE.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_ta-IN.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_te-IN.po +31 -4
- sempy_labs/_bpa_translation/_model/_translations_th-TH.po +31 -4
- sempy_labs/_bpa_translation/_model/_translations_tr-TR.po +32 -4
- sempy_labs/_bpa_translation/_model/_translations_uk-UA.po +100 -72
- sempy_labs/_bpa_translation/_model/_translations_zh-CN.po +23 -5
- sempy_labs/_bpa_translation/_model/_translations_zu-ZA.po +32 -4
- sempy_labs/_capacities.py +49 -14
- sempy_labs/_capacity_migration.py +1 -7
- sempy_labs/_data_pipelines.py +6 -0
- sempy_labs/_dataflows.py +118 -1
- sempy_labs/_dax.py +189 -3
- sempy_labs/_deployment_pipelines.py +13 -7
- sempy_labs/_environments.py +6 -0
- sempy_labs/_eventhouses.py +6 -0
- sempy_labs/_eventstreams.py +6 -0
- sempy_labs/_external_data_shares.py +6 -4
- sempy_labs/_generate_semantic_model.py +26 -3
- sempy_labs/_git.py +14 -14
- sempy_labs/_helper_functions.py +197 -1
- sempy_labs/_icons.py +55 -22
- sempy_labs/_kql_databases.py +6 -0
- sempy_labs/_kql_querysets.py +6 -0
- sempy_labs/_list_functions.py +1 -1
- sempy_labs/_managed_private_endpoints.py +166 -0
- sempy_labs/_mirrored_databases.py +428 -0
- sempy_labs/_mirrored_warehouses.py +2 -0
- sempy_labs/_ml_experiments.py +6 -0
- sempy_labs/_ml_models.py +7 -1
- sempy_labs/_model_bpa.py +215 -181
- sempy_labs/_model_bpa_bulk.py +46 -42
- sempy_labs/_model_bpa_rules.py +8 -3
- sempy_labs/_model_dependencies.py +41 -87
- sempy_labs/_notebooks.py +107 -12
- sempy_labs/_query_scale_out.py +8 -6
- sempy_labs/_refresh_semantic_model.py +299 -49
- sempy_labs/_spark.py +12 -5
- sempy_labs/_translations.py +2 -0
- sempy_labs/_vertipaq.py +89 -86
- sempy_labs/_warehouses.py +79 -0
- sempy_labs/_workloads.py +128 -0
- sempy_labs/_workspace_identity.py +4 -4
- sempy_labs/_workspaces.py +14 -1
- sempy_labs/admin/__init__.py +2 -0
- sempy_labs/admin/_basic_functions.py +131 -43
- sempy_labs/admin/_domains.py +18 -18
- sempy_labs/directlake/__init__.py +2 -0
- sempy_labs/directlake/_directlake_schema_sync.py +2 -1
- sempy_labs/directlake/_dl_helper.py +4 -1
- sempy_labs/directlake/_get_shared_expression.py +7 -1
- sempy_labs/directlake/_guardrails.py +2 -1
- sempy_labs/directlake/_show_unsupported_directlake_objects.py +1 -7
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +78 -0
- sempy_labs/directlake/_update_directlake_partition_entity.py +13 -32
- sempy_labs/directlake/_warm_cache.py +10 -9
- sempy_labs/lakehouse/_get_lakehouse_tables.py +6 -2
- sempy_labs/lakehouse/_shortcuts.py +4 -0
- sempy_labs/migration/_create_pqt_file.py +5 -2
- sempy_labs/migration/_migrate_calctables_to_lakehouse.py +3 -2
- sempy_labs/migration/_migrate_calctables_to_semantic_model.py +2 -0
- sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +2 -8
- sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +17 -0
- sempy_labs/migration/_migration_validation.py +2 -0
- sempy_labs/migration/_refresh_calc_tables.py +1 -0
- sempy_labs/report/__init__.py +6 -1
- sempy_labs/report/_download_report.py +75 -0
- sempy_labs/report/_generate_report.py +6 -0
- sempy_labs/report/_paginated.py +74 -0
- sempy_labs/report/_report_functions.py +6 -0
- sempy_labs/report/_report_rebind.py +2 -0
- sempy_labs/report/_reportwrapper.py +4 -2
- sempy_labs/tom/_model.py +135 -68
- {semantic_link_labs-0.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import sempy.fabric as fabric
|
|
2
|
-
from typing import Optional, List, Union
|
|
2
|
+
from typing import Optional, List, Union, Tuple
|
|
3
3
|
from uuid import UUID
|
|
4
4
|
import sempy_labs._icons as icons
|
|
5
5
|
from sempy.fabric.exceptions import FabricHTTPException
|
|
@@ -10,18 +10,26 @@ from sempy_labs._helper_functions import (
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
import pandas as pd
|
|
12
12
|
import time
|
|
13
|
+
import urllib.parse
|
|
14
|
+
from datetime import datetime
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
def list_workspaces(
|
|
16
|
-
top: Optional[int] = 5000,
|
|
18
|
+
top: Optional[int] = 5000,
|
|
19
|
+
filter: Optional[str] = None,
|
|
20
|
+
skip: Optional[int] = None,
|
|
17
21
|
) -> pd.DataFrame:
|
|
18
22
|
"""
|
|
19
23
|
Lists workspaces for the organization. This function is the admin version of list_workspaces.
|
|
20
24
|
|
|
25
|
+
This is a wrapper function for the following API: `Admin - Groups GetGroupsAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-get-groups-as-admin>`_.
|
|
26
|
+
|
|
21
27
|
Parameters
|
|
22
28
|
----------
|
|
23
29
|
top : int, default=5000
|
|
24
30
|
Returns only the first n results. This parameter is mandatory and must be in the range of 1-5000.
|
|
31
|
+
filter : str, default=None
|
|
32
|
+
Returns a subset of a results based on `Odata filter <https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_SystemQueryOptions>`_ query parameter condition.
|
|
25
33
|
skip : int, default=None
|
|
26
34
|
Skips the first n results. Use with top to fetch results beyond the first 5000.
|
|
27
35
|
|
|
@@ -48,6 +56,8 @@ def list_workspaces(
|
|
|
48
56
|
url = f"/v1.0/myorg/admin/groups?$top={top}"
|
|
49
57
|
if skip is not None:
|
|
50
58
|
url = f"{url}&$skip={skip}"
|
|
59
|
+
if filter is not None:
|
|
60
|
+
url = f"{url}&$filter={filter}"
|
|
51
61
|
|
|
52
62
|
client = fabric.PowerBIRestClient()
|
|
53
63
|
response = client.get(url)
|
|
@@ -91,6 +101,8 @@ def assign_workspaces_to_capacity(
|
|
|
91
101
|
"""
|
|
92
102
|
Assigns a workspace to a capacity. This function is the admin version.
|
|
93
103
|
|
|
104
|
+
This is a wrapper function for the following API: `Admin - Capacities AssignWorkspacesToCapacity <https://learn.microsoft.com/rest/api/power-bi/admin/capacities-assign-workspaces-to-capacity>`_.
|
|
105
|
+
|
|
94
106
|
Parameters
|
|
95
107
|
----------
|
|
96
108
|
source_capacity : str
|
|
@@ -113,9 +125,6 @@ def assign_workspaces_to_capacity(
|
|
|
113
125
|
target_capacity_id = dfC_filt["Capacity Id"].iloc[0]
|
|
114
126
|
|
|
115
127
|
if workspace is None:
|
|
116
|
-
# workspaces = fabric.list_workspaces(
|
|
117
|
-
# filter=f"capacityId eq '{source_capacity_id.upper()}'"
|
|
118
|
-
# )["Id"].values
|
|
119
128
|
dfW = list_workspaces()
|
|
120
129
|
dfW = dfW[dfW["Capacity Id"].str.upper() == source_capacity_id.upper()]
|
|
121
130
|
workspaces = dfW["Id"].tolist()
|
|
@@ -153,6 +162,8 @@ def list_capacities() -> pd.DataFrame:
|
|
|
153
162
|
"""
|
|
154
163
|
Shows the a list of capacities and their properties. This function is the admin version.
|
|
155
164
|
|
|
165
|
+
This is a wrapper function for the following API: `Admin - Get Capacities As Admin <https://learn.microsoft.com/rest/api/power-bi/admin/get-capacities-as-admin>`_.
|
|
166
|
+
|
|
156
167
|
Returns
|
|
157
168
|
-------
|
|
158
169
|
pandas.DataFrame
|
|
@@ -189,14 +200,14 @@ def list_tenant_settings() -> pd.DataFrame:
|
|
|
189
200
|
"""
|
|
190
201
|
Lists all tenant settings.
|
|
191
202
|
|
|
203
|
+
This is a wrapper function for the following API: `Tenants - List Tenant Settings <https://learn.microsoft.com/rest/api/fabric/admin/tenants/list-tenant-settings>`_.
|
|
204
|
+
|
|
192
205
|
Returns
|
|
193
206
|
-------
|
|
194
207
|
pandas.DataFrame
|
|
195
208
|
A pandas dataframe showing the tenant settings.
|
|
196
209
|
"""
|
|
197
210
|
|
|
198
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/tenants/list-tenant-settings?tabs=HTTP
|
|
199
|
-
|
|
200
211
|
client = fabric.FabricRestClient()
|
|
201
212
|
response = client.get("/v1/admin/tenantsettings")
|
|
202
213
|
|
|
@@ -262,7 +273,9 @@ def _list_capacities_meta() -> pd.DataFrame:
|
|
|
262
273
|
|
|
263
274
|
def unassign_workspaces_from_capacity(workspaces: str | List[str]):
|
|
264
275
|
"""
|
|
265
|
-
Unassigns workspace(s) from their capacity.
|
|
276
|
+
Unassigns workspace(s) from their capacity.
|
|
277
|
+
|
|
278
|
+
This is a wrapper function for the following API: `Admin - Capacities UnassignWorkspacesFromCapacity <https://learn.microsoft.com/rest/api/power-bi/admin/capacities-unassign-workspaces-from-capacity>`_.
|
|
266
279
|
|
|
267
280
|
Parameters
|
|
268
281
|
----------
|
|
@@ -270,8 +283,6 @@ def unassign_workspaces_from_capacity(workspaces: str | List[str]):
|
|
|
270
283
|
The Fabric workspace name(s).
|
|
271
284
|
"""
|
|
272
285
|
|
|
273
|
-
# https://learn.microsoft.com/en-us/rest/api/power-bi/admin/capacities-unassign-workspaces-from-capacity
|
|
274
|
-
|
|
275
286
|
if isinstance(workspaces, str):
|
|
276
287
|
workspaces = [workspaces]
|
|
277
288
|
|
|
@@ -293,14 +304,14 @@ def list_external_data_shares():
|
|
|
293
304
|
"""
|
|
294
305
|
Lists external data shares in the tenant. This function is for admins.
|
|
295
306
|
|
|
307
|
+
This is a wrapper function for the following API: `External Data Shares - List External Data Shares <https://learn.microsoft.com/rest/api/fabric/admin/external-data-shares/list-external-data-shares>`_.
|
|
308
|
+
|
|
296
309
|
Returns
|
|
297
310
|
-------
|
|
298
311
|
pandas.DataFrame
|
|
299
312
|
A pandas dataframe showing a list of external data shares in the tenant.
|
|
300
313
|
"""
|
|
301
314
|
|
|
302
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/external-data-shares/list-external-data-shares?tabs=HTTP
|
|
303
|
-
|
|
304
315
|
df = pd.DataFrame(
|
|
305
316
|
columns=[
|
|
306
317
|
"External Data Share Id",
|
|
@@ -355,6 +366,8 @@ def revoke_external_data_share(
|
|
|
355
366
|
"""
|
|
356
367
|
Revokes the specified external data share. Note: This action cannot be undone.
|
|
357
368
|
|
|
369
|
+
This is a wrapper function for the following API: `External Data Shares - Revoke External Data Share <https://learn.microsoft.com/rest/api/fabric/admin/external-data-shares/revoke-external-data-share>`_.
|
|
370
|
+
|
|
358
371
|
Parameters
|
|
359
372
|
----------
|
|
360
373
|
external_data_share_id : UUID
|
|
@@ -365,8 +378,6 @@ def revoke_external_data_share(
|
|
|
365
378
|
The Fabric workspace name.
|
|
366
379
|
"""
|
|
367
380
|
|
|
368
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/external-data-shares/revoke-external-data-share?tabs=HTTP
|
|
369
|
-
|
|
370
381
|
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
371
382
|
|
|
372
383
|
client = fabric.FabricRestClient()
|
|
@@ -384,23 +395,23 @@ def revoke_external_data_share(
|
|
|
384
395
|
|
|
385
396
|
def list_capacities_delegated_tenant_settings(
|
|
386
397
|
return_dataframe: bool = True,
|
|
387
|
-
) ->
|
|
398
|
+
) -> pd.DataFrame | dict:
|
|
388
399
|
"""
|
|
389
400
|
Returns list of tenant setting overrides that override at the capacities.
|
|
390
401
|
|
|
402
|
+
This is a wrapper function for the following API: `Tenants - List Capacities Tenant Settings Overrides <https://learn.microsoft.com/rest/api/fabric/admin/tenants/list-capacities-tenant-settings-overrides>`_.
|
|
403
|
+
|
|
391
404
|
Parameters
|
|
392
405
|
----------
|
|
393
406
|
return_dataframe : bool, default=True
|
|
394
|
-
If True, returns a dataframe. If False, returns a dictionary
|
|
407
|
+
If True, returns a dataframe. If False, returns a dictionary.
|
|
395
408
|
|
|
396
409
|
Returns
|
|
397
410
|
-------
|
|
398
|
-
pandas.DataFrame
|
|
411
|
+
pandas.DataFrame | dict
|
|
399
412
|
A pandas dataframe showing a list of tenant setting overrides that override at the capacities.
|
|
400
413
|
"""
|
|
401
414
|
|
|
402
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/tenants/list-capacities-tenant-settings-overrides?tabs=HTTP
|
|
403
|
-
|
|
404
415
|
df = pd.DataFrame(
|
|
405
416
|
columns=[
|
|
406
417
|
"Capacity Id",
|
|
@@ -519,14 +530,14 @@ def list_datasets() -> pd.DataFrame:
|
|
|
519
530
|
"""
|
|
520
531
|
Shows a list of datasets for the organization.
|
|
521
532
|
|
|
533
|
+
This is a wrapper function for the following API: `Admin - Datasets GetDatasetsAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/datasets-get-datasets-as-admin>`_.
|
|
534
|
+
|
|
522
535
|
Returns
|
|
523
536
|
-------
|
|
524
537
|
pandas.DataFrame
|
|
525
538
|
A pandas dataframe showing a list of datasets for the organization.
|
|
526
539
|
"""
|
|
527
540
|
|
|
528
|
-
# https://learn.microsoft.com/en-us/rest/api/power-bi/admin/datasets-get-datasets-as-admin
|
|
529
|
-
|
|
530
541
|
df = pd.DataFrame(
|
|
531
542
|
columns=[
|
|
532
543
|
"Dataset Id",
|
|
@@ -609,6 +620,8 @@ def list_item_access_details(
|
|
|
609
620
|
"""
|
|
610
621
|
Returns a list of users (including groups and service principals) and lists their workspace roles.
|
|
611
622
|
|
|
623
|
+
This is a wrapper function for the following API: `Items - List Item Access Details <https://learn.microsoft.com/rest/api/fabric/admin/items/list-item-access-details>`_.
|
|
624
|
+
|
|
612
625
|
Parameters
|
|
613
626
|
----------
|
|
614
627
|
item_name : str
|
|
@@ -626,13 +639,8 @@ def list_item_access_details(
|
|
|
626
639
|
A pandas dataframe showing a list of users (including groups and service principals) and lists their workspace roles.
|
|
627
640
|
"""
|
|
628
641
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
workspace = fabric.resolve_workspace_name(workspace)
|
|
632
|
-
workspace_id = fabric.resolve_workspace_id(workspace)
|
|
633
|
-
item_id = fabric.resolve_item_id(
|
|
634
|
-
item_name=item_name, type=type, workspace=workspace
|
|
635
|
-
)
|
|
642
|
+
workspace_name, workspace_id = _resolve_workspace_name_and_id(workspace)
|
|
643
|
+
item_id = _resolve_item_id(item_name=item_name, type=type, workspace=workspace_name)
|
|
636
644
|
|
|
637
645
|
df = pd.DataFrame(
|
|
638
646
|
columns=[
|
|
@@ -678,7 +686,9 @@ def list_access_entities(
|
|
|
678
686
|
user_email_address: str,
|
|
679
687
|
) -> pd.DataFrame:
|
|
680
688
|
"""
|
|
681
|
-
Shows a list of permission details for Fabric and
|
|
689
|
+
Shows a list of permission details for Fabric and Power BI items the specified user can access.
|
|
690
|
+
|
|
691
|
+
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>`_.
|
|
682
692
|
|
|
683
693
|
Parameters
|
|
684
694
|
----------
|
|
@@ -688,11 +698,9 @@ def list_access_entities(
|
|
|
688
698
|
Returns
|
|
689
699
|
-------
|
|
690
700
|
pandas.DataFrame
|
|
691
|
-
A pandas dataframe showing a list of permission details for Fabric and
|
|
701
|
+
A pandas dataframe showing a list of permission details for Fabric and Power BI items the specified user can access.
|
|
692
702
|
"""
|
|
693
703
|
|
|
694
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/users/list-access-entities?tabs=HTTP
|
|
695
|
-
|
|
696
704
|
df = pd.DataFrame(
|
|
697
705
|
columns=[
|
|
698
706
|
"Item Id",
|
|
@@ -732,6 +740,8 @@ def list_workspace_access_details(
|
|
|
732
740
|
"""
|
|
733
741
|
Shows a list of users (including groups and Service Principals) that have access to the specified workspace.
|
|
734
742
|
|
|
743
|
+
This is a wrapper function for the following API: `Workspaces - List Workspace Access Details <https://learn.microsoft.com/rest/api/fabric/admin/workspaces/list-workspace-access-details>`_.
|
|
744
|
+
|
|
735
745
|
Parameters
|
|
736
746
|
----------
|
|
737
747
|
workspace : str, default=None
|
|
@@ -745,10 +755,7 @@ def list_workspace_access_details(
|
|
|
745
755
|
A pandas dataframe showing a list of users (including groups and Service Principals) that have access to the specified workspace.
|
|
746
756
|
"""
|
|
747
757
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
workspace_name = fabric.resolve_workspace_name(workspace)
|
|
751
|
-
workspace_id = fabric.resolve_workspace_id(workspace_name)
|
|
758
|
+
workspace_name, workspace_id = _resolve_workspace_name_and_id(workspace)
|
|
752
759
|
|
|
753
760
|
df = pd.DataFrame(
|
|
754
761
|
columns=[
|
|
@@ -779,6 +786,32 @@ def list_workspace_access_details(
|
|
|
779
786
|
return df
|
|
780
787
|
|
|
781
788
|
|
|
789
|
+
def _resolve_item_id(
|
|
790
|
+
item_name: str, type: str, workspace: Optional[str] = None
|
|
791
|
+
) -> UUID:
|
|
792
|
+
|
|
793
|
+
workspace_name, workspace_id = _resolve_workspace_name_and_id(workspace)
|
|
794
|
+
dfI = list_items(workspace=workspace_name, type=type)
|
|
795
|
+
dfI_filt = dfI[dfI["Item Name"] == item_name]
|
|
796
|
+
|
|
797
|
+
if len(dfI_filt) == 0:
|
|
798
|
+
raise ValueError(
|
|
799
|
+
f"The '{item_name}' {type} does not exist within the '{workspace_name}' workspace."
|
|
800
|
+
)
|
|
801
|
+
|
|
802
|
+
return dfI_filt["Item Id"].iloc[0]
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
def _resolve_workspace_name_and_id(workspace: str) -> Tuple[str, UUID]:
|
|
806
|
+
|
|
807
|
+
filter_condition = urllib.parse.quote(workspace)
|
|
808
|
+
dfW_filt = list_workspaces(filter=f"name eq '{filter_condition}'")
|
|
809
|
+
workspace_name = dfW_filt["Name"].iloc[0]
|
|
810
|
+
workspace_id = dfW_filt["Id"].iloc[0]
|
|
811
|
+
|
|
812
|
+
return workspace_name, workspace_id
|
|
813
|
+
|
|
814
|
+
|
|
782
815
|
def list_items(
|
|
783
816
|
capacity_name: Optional[str] = None,
|
|
784
817
|
workspace: Optional[str] = None,
|
|
@@ -786,7 +819,9 @@ def list_items(
|
|
|
786
819
|
type: Optional[str] = None,
|
|
787
820
|
) -> pd.DataFrame:
|
|
788
821
|
"""
|
|
789
|
-
Shows a list of active Fabric and
|
|
822
|
+
Shows a list of active Fabric and Power BI items.
|
|
823
|
+
|
|
824
|
+
This is a wrapper function for the following API: `Items - List Items <https://learn.microsoft.com/rest/api/fabric/admin/items/list-items>`_.
|
|
790
825
|
|
|
791
826
|
Parameters
|
|
792
827
|
----------
|
|
@@ -807,8 +842,6 @@ def list_items(
|
|
|
807
842
|
A pandas dataframe showing a list of active Fabric and Power BI items.
|
|
808
843
|
"""
|
|
809
844
|
|
|
810
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/items/list-items?tabs=HTTP
|
|
811
|
-
|
|
812
845
|
url = "/v1/admin/items?"
|
|
813
846
|
|
|
814
847
|
df = pd.DataFrame(
|
|
@@ -829,8 +862,7 @@ def list_items(
|
|
|
829
862
|
)
|
|
830
863
|
|
|
831
864
|
if workspace is not None:
|
|
832
|
-
|
|
833
|
-
workspace_id = fabric.resolve_workspace_id(workspace)
|
|
865
|
+
workspace_name, workspace_id = _resolve_workspace_name_and_id(workspace)
|
|
834
866
|
url += f"workspaceId={workspace_id}&"
|
|
835
867
|
if capacity_name is not None:
|
|
836
868
|
dfC = list_capacities()
|
|
@@ -891,6 +923,8 @@ def list_activity_events(
|
|
|
891
923
|
"""
|
|
892
924
|
Shows a list of audit activity events for a tenant.
|
|
893
925
|
|
|
926
|
+
This is a wrapper function for the following API: `Admin - Get Activity Events <https://learn.microsoft.com/rest/api/power-bi/admin/get-activity-events>`_.
|
|
927
|
+
|
|
894
928
|
Parameters
|
|
895
929
|
----------
|
|
896
930
|
start_time : str
|
|
@@ -908,7 +942,13 @@ def list_activity_events(
|
|
|
908
942
|
A pandas dataframe showing a list of audit activity events for a tenant.
|
|
909
943
|
"""
|
|
910
944
|
|
|
911
|
-
|
|
945
|
+
start_dt = datetime.strptime(start_time, "%Y-%m-%dT%H:%M:%S")
|
|
946
|
+
end_dt = datetime.strptime(end_time, "%Y-%m-%dT%H:%M:%S")
|
|
947
|
+
|
|
948
|
+
if not start_dt.date() == end_dt.date():
|
|
949
|
+
raise ValueError(
|
|
950
|
+
f"{icons.red_dot} Start and End Times must be within the same UTC day. Please refer to the documentation here: https://learn.microsoft.com/rest/api/power-bi/admin/get-activity-events#get-audit-activity-events-within-a-time-window-and-for-a-specific-activity-type-and-user-id-example"
|
|
951
|
+
)
|
|
912
952
|
|
|
913
953
|
df = pd.DataFrame(
|
|
914
954
|
columns=[
|
|
@@ -948,7 +988,7 @@ def list_activity_events(
|
|
|
948
988
|
conditions.append(f"UserId{space}eq{space}{tic}{user_id_filter}{tic}")
|
|
949
989
|
|
|
950
990
|
filter_value = (
|
|
951
|
-
f"
|
|
991
|
+
f"&$filter={f'{space}and{space}'.join(conditions)}" if conditions else ""
|
|
952
992
|
)
|
|
953
993
|
|
|
954
994
|
full_url = f"{base_url}?startDateTime={tic}{start_time}{tic}&endDateTime={tic}{end_time}{tic}{filter_value}"
|
|
@@ -988,4 +1028,52 @@ def list_activity_events(
|
|
|
988
1028
|
ignore_index=True,
|
|
989
1029
|
)
|
|
990
1030
|
|
|
1031
|
+
df["Creation Time"] = pd.to_datetime(df["Creation Time"])
|
|
1032
|
+
|
|
1033
|
+
return df
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
def list_modified_workspaces(
|
|
1037
|
+
modified_since: Optional[str] = None,
|
|
1038
|
+
exclude_inactive_workspaces: bool = False,
|
|
1039
|
+
exclude_personal_workspaces: bool = False,
|
|
1040
|
+
) -> pd.DataFrame:
|
|
1041
|
+
"""
|
|
1042
|
+
Gets a list of workspace IDs in the organization.
|
|
1043
|
+
|
|
1044
|
+
This is a wrapper function for the following API: `Admin - WorkspaceInfo GetModifiedWorkspaces <https://learn.microsoft.com/rest/api/power-bi/admin/workspace-info-get-modified-workspaces>`_.
|
|
1045
|
+
|
|
1046
|
+
Parameters
|
|
1047
|
+
----------
|
|
1048
|
+
modified_since : str
|
|
1049
|
+
Last modified date (must be in ISO 8601 compliant UTC format). Example: "2024-11-02T05:51:30.0000000Z".
|
|
1050
|
+
exclude_inactive_workspaces : bool, default=False
|
|
1051
|
+
Whether to exclude inactive workspaces.
|
|
1052
|
+
exclude_personal_workspaces : bool, default=False
|
|
1053
|
+
Whether to exclude personal workspaces.
|
|
1054
|
+
|
|
1055
|
+
Returns
|
|
1056
|
+
-------
|
|
1057
|
+
pandas.DataFrame
|
|
1058
|
+
A pandas dataframe showing a list of workspace IDs in the organization.
|
|
1059
|
+
"""
|
|
1060
|
+
|
|
1061
|
+
client = fabric.PowerBIRestClient()
|
|
1062
|
+
url = "/v1.0/myorg/admin/workspaces/modified?"
|
|
1063
|
+
|
|
1064
|
+
if modified_since is not None:
|
|
1065
|
+
url += f"modifiedSince={modified_since}&"
|
|
1066
|
+
if exclude_inactive_workspaces:
|
|
1067
|
+
url += f"excludeInActiveWorkspaces={exclude_inactive_workspaces}&"
|
|
1068
|
+
if exclude_personal_workspaces:
|
|
1069
|
+
url += f"excludePersonalWorkspaces={exclude_personal_workspaces}&"
|
|
1070
|
+
|
|
1071
|
+
url = url.rstrip("&").rstrip("?")
|
|
1072
|
+
|
|
1073
|
+
response = client.get(url)
|
|
1074
|
+
if response.status_code != 200:
|
|
1075
|
+
raise FabricHTTPException(response)
|
|
1076
|
+
|
|
1077
|
+
df = pd.DataFrame(response.json()).rename(columns={"id": "Workspace Id"})
|
|
1078
|
+
|
|
991
1079
|
return df
|
sempy_labs/admin/_domains.py
CHANGED
|
@@ -34,6 +34,8 @@ def list_domains(non_empty_only: bool = False) -> pd.DataFrame:
|
|
|
34
34
|
"""
|
|
35
35
|
Shows a list of domains.
|
|
36
36
|
|
|
37
|
+
This is a wrapper function for the following API: `Domains - List Domains <https://learn.microsoft.com/rest/api/fabric/admin/domains/list-domains>`_.
|
|
38
|
+
|
|
37
39
|
Parameters
|
|
38
40
|
----------
|
|
39
41
|
non_empty_only : bool, default=False
|
|
@@ -46,8 +48,6 @@ def list_domains(non_empty_only: bool = False) -> pd.DataFrame:
|
|
|
46
48
|
A pandas dataframe showing a list of the domains.
|
|
47
49
|
"""
|
|
48
50
|
|
|
49
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/list-domains?tabs=HTTP
|
|
50
|
-
|
|
51
51
|
df = pd.DataFrame(
|
|
52
52
|
columns=[
|
|
53
53
|
"Domain ID",
|
|
@@ -84,6 +84,8 @@ def list_domain_workspaces(domain_name: str) -> pd.DataFrame:
|
|
|
84
84
|
"""
|
|
85
85
|
Shows a list of workspaces within the domain.
|
|
86
86
|
|
|
87
|
+
This is a wrapper function for the following API: `Domains - List Domain Workspaces <https://learn.microsoft.com/rest/api/fabric/admin/domains/list-domain-workspaces>`_.
|
|
88
|
+
|
|
87
89
|
Parameters
|
|
88
90
|
----------
|
|
89
91
|
domain_name : str
|
|
@@ -95,8 +97,6 @@ def list_domain_workspaces(domain_name: str) -> pd.DataFrame:
|
|
|
95
97
|
A pandas dataframe showing a list of workspaces within the domain.
|
|
96
98
|
"""
|
|
97
99
|
|
|
98
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/list-domain-workspaces?tabs=HTTP
|
|
99
|
-
|
|
100
100
|
domain_id = resolve_domain_id(domain_name)
|
|
101
101
|
|
|
102
102
|
df = pd.DataFrame(columns=["Workspace ID", "Workspace Name"])
|
|
@@ -125,6 +125,8 @@ def create_domain(
|
|
|
125
125
|
"""
|
|
126
126
|
Creates a new domain.
|
|
127
127
|
|
|
128
|
+
This is a wrapper function for the following API: `Domains - Create Domain <https://learn.microsoft.com/rest/api/fabric/admin/domains/create-domain>`_.
|
|
129
|
+
|
|
128
130
|
Parameters
|
|
129
131
|
----------
|
|
130
132
|
domain_name : str
|
|
@@ -135,8 +137,6 @@ def create_domain(
|
|
|
135
137
|
The parent domain name.
|
|
136
138
|
"""
|
|
137
139
|
|
|
138
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/create-domain?tabs=HTTP
|
|
139
|
-
|
|
140
140
|
if parent_domain_name is not None:
|
|
141
141
|
parent_domain_id = resolve_domain_id(parent_domain_name)
|
|
142
142
|
|
|
@@ -160,14 +160,14 @@ def delete_domain(domain_name: str):
|
|
|
160
160
|
"""
|
|
161
161
|
Deletes a domain.
|
|
162
162
|
|
|
163
|
+
This is a wrapper function for the following API: `Domains - Delete Domain <https://learn.microsoft.com/rest/api/fabric/admin/domains/delete-domain>`_.
|
|
164
|
+
|
|
163
165
|
Parameters
|
|
164
166
|
----------
|
|
165
167
|
domain_name : str
|
|
166
168
|
The domain name.
|
|
167
169
|
"""
|
|
168
170
|
|
|
169
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/delete-domain?tabs=HTTP
|
|
170
|
-
|
|
171
171
|
domain_id = resolve_domain_id(domain_name)
|
|
172
172
|
|
|
173
173
|
client = fabric.FabricRestClient()
|
|
@@ -187,6 +187,8 @@ def update_domain(
|
|
|
187
187
|
"""
|
|
188
188
|
Updates a domain's properties.
|
|
189
189
|
|
|
190
|
+
This is a wrapper function for the following API: `Domains - Update Domain <https://learn.microsoft.com/rest/api/fabric/admin/domains/update-domain>`_.
|
|
191
|
+
|
|
190
192
|
Parameters
|
|
191
193
|
----------
|
|
192
194
|
domain_name : str
|
|
@@ -197,8 +199,6 @@ def update_domain(
|
|
|
197
199
|
The domain `contributor scope <https://learn.microsoft.com/rest/api/fabric/admin/domains/update-domain?tabs=HTTP#contributorsscopetype>`_.
|
|
198
200
|
"""
|
|
199
201
|
|
|
200
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/update-domain?tabs=HTTP
|
|
201
|
-
|
|
202
202
|
contributors_scopes = ["AdminsOnly", "AllTenant", "SpecificUsersAndGroups"]
|
|
203
203
|
|
|
204
204
|
if contributors_scope not in contributors_scopes:
|
|
@@ -231,6 +231,8 @@ def assign_domain_workspaces_by_capacities(
|
|
|
231
231
|
"""
|
|
232
232
|
Assigns all workspaces that reside on the specified capacities to the specified domain.
|
|
233
233
|
|
|
234
|
+
This is a wrapper function for the following API: `Domains - Assign Domain Workspaces By Capacities <https://learn.microsoft.com/rest/api/fabric/admin/domains/assign-domain-workspaces-by-capacities>`_.
|
|
235
|
+
|
|
234
236
|
Parameters
|
|
235
237
|
----------
|
|
236
238
|
domain_name : str
|
|
@@ -239,8 +241,6 @@ def assign_domain_workspaces_by_capacities(
|
|
|
239
241
|
The capacity names.
|
|
240
242
|
"""
|
|
241
243
|
|
|
242
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/assign-domain-workspaces-by-capacities?tabs=HTTP
|
|
243
|
-
|
|
244
244
|
from sempy_labs.admin import list_capacities
|
|
245
245
|
|
|
246
246
|
domain_id = resolve_domain_id(domain_name)
|
|
@@ -287,6 +287,8 @@ def assign_domain_workspaces(domain_name: str, workspace_names: str | List[str])
|
|
|
287
287
|
"""
|
|
288
288
|
Assigns workspaces to the specified domain by workspace.
|
|
289
289
|
|
|
290
|
+
This is a wrapper function for the following API: `Domains - Assign Domain Workspaces By Ids <https://learn.microsoft.com/rest/api/fabric/admin/domains/assign-domain-workspaces-by-ids>`_.
|
|
291
|
+
|
|
290
292
|
Parameters
|
|
291
293
|
----------
|
|
292
294
|
domain_name : str
|
|
@@ -295,8 +297,6 @@ def assign_domain_workspaces(domain_name: str, workspace_names: str | List[str])
|
|
|
295
297
|
The Fabric workspace(s).
|
|
296
298
|
"""
|
|
297
299
|
|
|
298
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/assign-domain-workspaces-by-ids?tabs=HTTP
|
|
299
|
-
|
|
300
300
|
domain_id = resolve_domain_id(domain_name=domain_name)
|
|
301
301
|
|
|
302
302
|
if isinstance(workspace_names, str):
|
|
@@ -340,14 +340,14 @@ def unassign_all_domain_workspaces(domain_name: str):
|
|
|
340
340
|
"""
|
|
341
341
|
Unassigns all workspaces from the specified domain.
|
|
342
342
|
|
|
343
|
+
This is a wrapper function for the following API: `Domains - Unassign All Domain Workspaces <https://learn.microsoft.com/rest/api/fabric/admin/domains/unassign-all-domain-workspaces>`_.
|
|
344
|
+
|
|
343
345
|
Parameters
|
|
344
346
|
----------
|
|
345
347
|
domain_name : str
|
|
346
348
|
The domain name.
|
|
347
349
|
"""
|
|
348
350
|
|
|
349
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/unassign-all-domain-workspaces?tabs=HTTP
|
|
350
|
-
|
|
351
351
|
domain_id = resolve_domain_id(domain_name=domain_name)
|
|
352
352
|
|
|
353
353
|
client = fabric.FabricRestClient()
|
|
@@ -364,6 +364,8 @@ def unassign_domain_workspaces(domain_name: str, workspace_names: str | List[str
|
|
|
364
364
|
"""
|
|
365
365
|
Unassigns workspaces from the specified domain by workspace.
|
|
366
366
|
|
|
367
|
+
This is a wrapper function for the following API: `Domains - Unassign Domain Workspaces By Ids <https://learn.microsoft.com/rest/api/fabric/admin/domains/unassign-domain-workspaces-by-ids>`_.
|
|
368
|
+
|
|
367
369
|
Parameters
|
|
368
370
|
----------
|
|
369
371
|
domain_name : str
|
|
@@ -372,8 +374,6 @@ def unassign_domain_workspaces(domain_name: str, workspace_names: str | List[str
|
|
|
372
374
|
The Fabric workspace(s).
|
|
373
375
|
"""
|
|
374
376
|
|
|
375
|
-
# https://learn.microsoft.com/en-us/rest/api/fabric/admin/domains/unassign-domain-workspaces-by-ids?tabs=HTTP
|
|
376
|
-
|
|
377
377
|
domain_id = resolve_domain_id(domain_name=domain_name)
|
|
378
378
|
|
|
379
379
|
if isinstance(workspace_names, str):
|
|
@@ -21,6 +21,7 @@ from sempy_labs.directlake._show_unsupported_directlake_objects import (
|
|
|
21
21
|
)
|
|
22
22
|
from sempy_labs.directlake._update_directlake_model_lakehouse_connection import (
|
|
23
23
|
update_direct_lake_model_lakehouse_connection,
|
|
24
|
+
update_direct_lake_model_connection,
|
|
24
25
|
)
|
|
25
26
|
from sempy_labs.directlake._update_directlake_partition_entity import (
|
|
26
27
|
update_direct_lake_partition_entity,
|
|
@@ -50,4 +51,5 @@ __all__ = [
|
|
|
50
51
|
"add_table_to_direct_lake_semantic_model",
|
|
51
52
|
"generate_direct_lake_semantic_model",
|
|
52
53
|
"get_direct_lake_source",
|
|
54
|
+
"update_direct_lake_model_connection",
|
|
53
55
|
]
|
|
@@ -3,6 +3,7 @@ import sempy.fabric as fabric
|
|
|
3
3
|
from sempy_labs.lakehouse import get_lakehouse_columns
|
|
4
4
|
from sempy_labs.directlake._dl_helper import get_direct_lake_source
|
|
5
5
|
from sempy_labs.tom import connect_semantic_model
|
|
6
|
+
from sempy_labs._helper_functions import _convert_data_type
|
|
6
7
|
from typing import Optional
|
|
7
8
|
from sempy._utils._log import log
|
|
8
9
|
import sempy_labs._icons as icons
|
|
@@ -88,7 +89,7 @@ def direct_lake_schema_sync(
|
|
|
88
89
|
f"{icons.yellow_dot} The '{lakeCName}' column exists in the '{lakeTName}' lakehouse table but not in the '{dataset}' semantic model within the '{workspace}' workspace."
|
|
89
90
|
)
|
|
90
91
|
if add_to_model:
|
|
91
|
-
dt =
|
|
92
|
+
dt = _convert_data_type(dType)
|
|
92
93
|
tom.add_data_column(
|
|
93
94
|
table_name=table_name,
|
|
94
95
|
column_name=lakeCName,
|
|
@@ -9,6 +9,7 @@ from sempy_labs._helper_functions import (
|
|
|
9
9
|
retry,
|
|
10
10
|
resolve_dataset_id,
|
|
11
11
|
resolve_lakehouse_name,
|
|
12
|
+
_convert_data_type,
|
|
12
13
|
)
|
|
13
14
|
|
|
14
15
|
|
|
@@ -130,6 +131,8 @@ def generate_direct_lake_semantic_model(
|
|
|
130
131
|
|
|
131
132
|
dfLT = get_lakehouse_tables(lakehouse=lakehouse, workspace=lakehouse_workspace)
|
|
132
133
|
|
|
134
|
+
icons.sll_tags.append("GenerateDLModel")
|
|
135
|
+
|
|
133
136
|
# Validate lakehouse tables
|
|
134
137
|
for t in lakehouse_tables:
|
|
135
138
|
if t not in dfLT["Table Name"].values:
|
|
@@ -178,7 +181,7 @@ def generate_direct_lake_semantic_model(
|
|
|
178
181
|
for i, r in dfLC_filt.iterrows():
|
|
179
182
|
lakeCName = r["Column Name"]
|
|
180
183
|
dType = r["Data Type"]
|
|
181
|
-
dt =
|
|
184
|
+
dt = _convert_data_type(dType)
|
|
182
185
|
tom.add_data_column(
|
|
183
186
|
table_name=t,
|
|
184
187
|
column_name=lakeCName,
|
|
@@ -30,7 +30,7 @@ def get_shared_expression(
|
|
|
30
30
|
workspace = fabric.resolve_workspace_name(workspace)
|
|
31
31
|
if lakehouse is None:
|
|
32
32
|
lakehouse_id = fabric.get_lakehouse_id()
|
|
33
|
-
lakehouse = resolve_lakehouse_name(lakehouse_id)
|
|
33
|
+
lakehouse = resolve_lakehouse_name(lakehouse_id, workspace)
|
|
34
34
|
|
|
35
35
|
dfL = list_lakehouses(workspace=workspace)
|
|
36
36
|
lakeDetail = dfL[dfL["Lakehouse Name"] == lakehouse]
|
|
@@ -39,6 +39,12 @@ def get_shared_expression(
|
|
|
39
39
|
sqlepid = lakeDetail["SQL Endpoint ID"].iloc[0]
|
|
40
40
|
provStatus = lakeDetail["SQL Endpoint Provisioning Status"].iloc[0]
|
|
41
41
|
|
|
42
|
+
parts = sqlEPCS.split(".", 1)
|
|
43
|
+
if parts:
|
|
44
|
+
parts[0] = parts[0].upper()
|
|
45
|
+
|
|
46
|
+
sqlEPCS = ".".join(parts)
|
|
47
|
+
|
|
42
48
|
if provStatus == "InProgress":
|
|
43
49
|
raise ValueError(
|
|
44
50
|
f"{icons.red_dot} The SQL Endpoint for the '{lakehouse}' lakehouse within the '{workspace}' workspace has not yet been provisioned. Please wait until it has been provisioned."
|
|
@@ -81,6 +81,7 @@ def get_directlake_guardrails_for_sku(sku_size: str) -> pd.DataFrame:
|
|
|
81
81
|
"""
|
|
82
82
|
|
|
83
83
|
df = get_direct_lake_guardrails()
|
|
84
|
-
|
|
84
|
+
col_name = df.columns[0]
|
|
85
|
+
filtered_df = df[df[col_name] == sku_size]
|
|
85
86
|
|
|
86
87
|
return filtered_df
|
|
@@ -59,13 +59,7 @@ def show_unsupported_direct_lake_objects(
|
|
|
59
59
|
dfR["From Column Data Type"] = merged_from["Data Type"]
|
|
60
60
|
dfR["To Column Data Type"] = merged_to["Data Type"]
|
|
61
61
|
|
|
62
|
-
dfR_filt = dfR[
|
|
63
|
-
(
|
|
64
|
-
(dfR["From Column Data Type"] == "DateTime")
|
|
65
|
-
| (dfR["To Column Data Type"] == "DateTime")
|
|
66
|
-
)
|
|
67
|
-
| (dfR["From Column Data Type"] != dfR["To Column Data Type"])
|
|
68
|
-
]
|
|
62
|
+
dfR_filt = dfR[(dfR["From Column Data Type"] != dfR["To Column Data Type"])]
|
|
69
63
|
r = dfR_filt[
|
|
70
64
|
[
|
|
71
65
|
"From Table",
|