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.

Files changed (109) hide show
  1. {semantic_link_labs-0.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/METADATA +38 -8
  2. {semantic_link_labs-0.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/RECORD +109 -104
  3. {semantic_link_labs-0.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +53 -1
  5. sempy_labs/_bpa_translation/_model/_translations_am-ET.po +24 -5
  6. sempy_labs/_bpa_translation/_model/_translations_ar-AE.po +28 -4
  7. sempy_labs/_bpa_translation/_model/_translations_bg-BG.po +34 -4
  8. sempy_labs/_bpa_translation/_model/_translations_ca-ES.po +33 -4
  9. sempy_labs/_bpa_translation/_model/_translations_cs-CZ.po +31 -4
  10. sempy_labs/_bpa_translation/_model/_translations_da-DK.po +31 -4
  11. sempy_labs/_bpa_translation/_model/_translations_de-DE.po +34 -4
  12. sempy_labs/_bpa_translation/_model/_translations_el-GR.po +36 -4
  13. sempy_labs/_bpa_translation/_model/_translations_es-ES.po +90 -58
  14. sempy_labs/_bpa_translation/_model/_translations_fa-IR.po +31 -5
  15. sempy_labs/_bpa_translation/_model/_translations_fi-FI.po +31 -4
  16. sempy_labs/_bpa_translation/_model/_translations_fr-FR.po +34 -4
  17. sempy_labs/_bpa_translation/_model/_translations_ga-IE.po +34 -4
  18. sempy_labs/_bpa_translation/_model/_translations_he-IL.po +28 -4
  19. sempy_labs/_bpa_translation/_model/_translations_hi-IN.po +32 -4
  20. sempy_labs/_bpa_translation/_model/_translations_hu-HU.po +32 -4
  21. sempy_labs/_bpa_translation/_model/_translations_id-ID.po +32 -4
  22. sempy_labs/_bpa_translation/_model/_translations_is-IS.po +31 -4
  23. sempy_labs/_bpa_translation/_model/_translations_it-IT.po +34 -4
  24. sempy_labs/_bpa_translation/_model/_translations_ja-JP.po +24 -4
  25. sempy_labs/_bpa_translation/_model/_translations_ko-KR.po +72 -56
  26. sempy_labs/_bpa_translation/_model/_translations_mt-MT.po +34 -4
  27. sempy_labs/_bpa_translation/_model/_translations_nl-NL.po +34 -4
  28. sempy_labs/_bpa_translation/_model/_translations_pl-PL.po +95 -71
  29. sempy_labs/_bpa_translation/_model/_translations_pt-BR.po +32 -4
  30. sempy_labs/_bpa_translation/_model/_translations_pt-PT.po +32 -4
  31. sempy_labs/_bpa_translation/_model/_translations_ro-RO.po +33 -4
  32. sempy_labs/_bpa_translation/_model/_translations_ru-RU.po +34 -4
  33. sempy_labs/_bpa_translation/_model/_translations_sk-SK.po +31 -4
  34. sempy_labs/_bpa_translation/_model/_translations_sl-SL.po +32 -4
  35. sempy_labs/_bpa_translation/_model/_translations_sv-SE.po +32 -4
  36. sempy_labs/_bpa_translation/_model/_translations_ta-IN.po +32 -4
  37. sempy_labs/_bpa_translation/_model/_translations_te-IN.po +31 -4
  38. sempy_labs/_bpa_translation/_model/_translations_th-TH.po +31 -4
  39. sempy_labs/_bpa_translation/_model/_translations_tr-TR.po +32 -4
  40. sempy_labs/_bpa_translation/_model/_translations_uk-UA.po +100 -72
  41. sempy_labs/_bpa_translation/_model/_translations_zh-CN.po +23 -5
  42. sempy_labs/_bpa_translation/_model/_translations_zu-ZA.po +32 -4
  43. sempy_labs/_capacities.py +49 -14
  44. sempy_labs/_capacity_migration.py +1 -7
  45. sempy_labs/_data_pipelines.py +6 -0
  46. sempy_labs/_dataflows.py +118 -1
  47. sempy_labs/_dax.py +189 -3
  48. sempy_labs/_deployment_pipelines.py +13 -7
  49. sempy_labs/_environments.py +6 -0
  50. sempy_labs/_eventhouses.py +6 -0
  51. sempy_labs/_eventstreams.py +6 -0
  52. sempy_labs/_external_data_shares.py +6 -4
  53. sempy_labs/_generate_semantic_model.py +26 -3
  54. sempy_labs/_git.py +14 -14
  55. sempy_labs/_helper_functions.py +197 -1
  56. sempy_labs/_icons.py +55 -22
  57. sempy_labs/_kql_databases.py +6 -0
  58. sempy_labs/_kql_querysets.py +6 -0
  59. sempy_labs/_list_functions.py +1 -1
  60. sempy_labs/_managed_private_endpoints.py +166 -0
  61. sempy_labs/_mirrored_databases.py +428 -0
  62. sempy_labs/_mirrored_warehouses.py +2 -0
  63. sempy_labs/_ml_experiments.py +6 -0
  64. sempy_labs/_ml_models.py +7 -1
  65. sempy_labs/_model_bpa.py +215 -181
  66. sempy_labs/_model_bpa_bulk.py +46 -42
  67. sempy_labs/_model_bpa_rules.py +8 -3
  68. sempy_labs/_model_dependencies.py +41 -87
  69. sempy_labs/_notebooks.py +107 -12
  70. sempy_labs/_query_scale_out.py +8 -6
  71. sempy_labs/_refresh_semantic_model.py +299 -49
  72. sempy_labs/_spark.py +12 -5
  73. sempy_labs/_translations.py +2 -0
  74. sempy_labs/_vertipaq.py +89 -86
  75. sempy_labs/_warehouses.py +79 -0
  76. sempy_labs/_workloads.py +128 -0
  77. sempy_labs/_workspace_identity.py +4 -4
  78. sempy_labs/_workspaces.py +14 -1
  79. sempy_labs/admin/__init__.py +2 -0
  80. sempy_labs/admin/_basic_functions.py +131 -43
  81. sempy_labs/admin/_domains.py +18 -18
  82. sempy_labs/directlake/__init__.py +2 -0
  83. sempy_labs/directlake/_directlake_schema_sync.py +2 -1
  84. sempy_labs/directlake/_dl_helper.py +4 -1
  85. sempy_labs/directlake/_get_shared_expression.py +7 -1
  86. sempy_labs/directlake/_guardrails.py +2 -1
  87. sempy_labs/directlake/_show_unsupported_directlake_objects.py +1 -7
  88. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +78 -0
  89. sempy_labs/directlake/_update_directlake_partition_entity.py +13 -32
  90. sempy_labs/directlake/_warm_cache.py +10 -9
  91. sempy_labs/lakehouse/_get_lakehouse_tables.py +6 -2
  92. sempy_labs/lakehouse/_shortcuts.py +4 -0
  93. sempy_labs/migration/_create_pqt_file.py +5 -2
  94. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +3 -2
  95. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +2 -0
  96. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +2 -8
  97. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +17 -0
  98. sempy_labs/migration/_migration_validation.py +2 -0
  99. sempy_labs/migration/_refresh_calc_tables.py +1 -0
  100. sempy_labs/report/__init__.py +6 -1
  101. sempy_labs/report/_download_report.py +75 -0
  102. sempy_labs/report/_generate_report.py +6 -0
  103. sempy_labs/report/_paginated.py +74 -0
  104. sempy_labs/report/_report_functions.py +6 -0
  105. sempy_labs/report/_report_rebind.py +2 -0
  106. sempy_labs/report/_reportwrapper.py +4 -2
  107. sempy_labs/tom/_model.py +135 -68
  108. {semantic_link_labs-0.8.3.dist-info → semantic_link_labs-0.8.5.dist-info}/LICENSE +0 -0
  109. {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, skip: Optional[int] = None
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. This function is the admin version of list_workspaces.
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
- ) -> Optional[pd.DataFrame | dict]:
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
- # https://learn.microsoft.com/en-us/rest/api/fabric/admin/items/list-item-access-details?tabs=HTTP
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 PowerBI items the specified user can access.
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 PowerBI items the specified user can access.
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
- # https://learn.microsoft.com/en-us/rest/api/fabric/admin/workspaces/list-workspace-access-details?tabs=HTTP
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 PowerBI items.
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
- workspace = fabric.resolve_workspace_name(workspace)
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
- # https://learn.microsoft.com/en-us/rest/api/power-bi/admin/get-activity-events
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"&filter={f'{space}and{space}'.join(conditions)}" if conditions else ""
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
@@ -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 = icons.data_type_mapping.get(dType)
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 = icons.data_type_mapping.get(dType)
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
- filtered_df = df[df["Fabric SKUs"] == sku_size]
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",