semantic-link-labs 0.10.0__py3-none-any.whl → 0.11.0__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 (95) hide show
  1. {semantic_link_labs-0.10.0.dist-info → semantic_link_labs-0.11.0.dist-info}/METADATA +9 -6
  2. {semantic_link_labs-0.10.0.dist-info → semantic_link_labs-0.11.0.dist-info}/RECORD +95 -87
  3. sempy_labs/__init__.py +11 -1
  4. sempy_labs/_a_lib_info.py +2 -0
  5. sempy_labs/_capacities.py +2 -0
  6. sempy_labs/_connections.py +11 -0
  7. sempy_labs/_dashboards.py +9 -4
  8. sempy_labs/_data_pipelines.py +5 -0
  9. sempy_labs/_dataflows.py +284 -17
  10. sempy_labs/_daxformatter.py +80 -0
  11. sempy_labs/_delta_analyzer_history.py +4 -1
  12. sempy_labs/_deployment_pipelines.py +4 -0
  13. sempy_labs/_documentation.py +3 -0
  14. sempy_labs/_environments.py +10 -1
  15. sempy_labs/_eventhouses.py +12 -5
  16. sempy_labs/_eventstreams.py +11 -3
  17. sempy_labs/_external_data_shares.py +8 -2
  18. sempy_labs/_gateways.py +26 -5
  19. sempy_labs/_git.py +11 -0
  20. sempy_labs/_graphQL.py +10 -3
  21. sempy_labs/_helper_functions.py +62 -10
  22. sempy_labs/_job_scheduler.py +54 -7
  23. sempy_labs/_kql_databases.py +11 -2
  24. sempy_labs/_kql_querysets.py +11 -3
  25. sempy_labs/_list_functions.py +17 -45
  26. sempy_labs/_managed_private_endpoints.py +11 -2
  27. sempy_labs/_mirrored_databases.py +17 -3
  28. sempy_labs/_mirrored_warehouses.py +9 -3
  29. sempy_labs/_ml_experiments.py +11 -3
  30. sempy_labs/_ml_models.py +11 -3
  31. sempy_labs/_model_bpa_rules.py +2 -0
  32. sempy_labs/_mounted_data_factories.py +12 -8
  33. sempy_labs/_notebooks.py +6 -3
  34. sempy_labs/_refresh_semantic_model.py +1 -0
  35. sempy_labs/_semantic_models.py +107 -0
  36. sempy_labs/_spark.py +7 -0
  37. sempy_labs/_sql_endpoints.py +208 -0
  38. sempy_labs/_sqldatabase.py +13 -4
  39. sempy_labs/_tags.py +5 -1
  40. sempy_labs/_user_delegation_key.py +2 -0
  41. sempy_labs/_variable_libraries.py +3 -1
  42. sempy_labs/_warehouses.py +13 -3
  43. sempy_labs/_workloads.py +3 -0
  44. sempy_labs/_workspace_identity.py +3 -0
  45. sempy_labs/_workspaces.py +14 -1
  46. sempy_labs/admin/__init__.py +2 -0
  47. sempy_labs/admin/_activities.py +6 -5
  48. sempy_labs/admin/_apps.py +31 -31
  49. sempy_labs/admin/_artifacts.py +8 -3
  50. sempy_labs/admin/_basic_functions.py +5 -0
  51. sempy_labs/admin/_capacities.py +39 -28
  52. sempy_labs/admin/_datasets.py +51 -51
  53. sempy_labs/admin/_domains.py +17 -1
  54. sempy_labs/admin/_external_data_share.py +8 -2
  55. sempy_labs/admin/_git.py +14 -9
  56. sempy_labs/admin/_items.py +15 -2
  57. sempy_labs/admin/_reports.py +64 -65
  58. sempy_labs/admin/_shared.py +7 -1
  59. sempy_labs/admin/_tags.py +5 -0
  60. sempy_labs/admin/_tenant.py +5 -2
  61. sempy_labs/admin/_users.py +9 -3
  62. sempy_labs/admin/_workspaces.py +88 -0
  63. sempy_labs/directlake/_dl_helper.py +2 -0
  64. sempy_labs/directlake/_generate_shared_expression.py +2 -0
  65. sempy_labs/directlake/_get_directlake_lakehouse.py +2 -4
  66. sempy_labs/directlake/_get_shared_expression.py +2 -0
  67. sempy_labs/directlake/_guardrails.py +2 -0
  68. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +5 -3
  69. sempy_labs/directlake/_warm_cache.py +1 -0
  70. sempy_labs/graph/_groups.py +22 -7
  71. sempy_labs/graph/_teams.py +7 -2
  72. sempy_labs/graph/_users.py +1 -0
  73. sempy_labs/lakehouse/_blobs.py +1 -0
  74. sempy_labs/lakehouse/_get_lakehouse_tables.py +88 -27
  75. sempy_labs/lakehouse/_helper.py +2 -0
  76. sempy_labs/lakehouse/_lakehouse.py +38 -5
  77. sempy_labs/lakehouse/_livy_sessions.py +2 -1
  78. sempy_labs/lakehouse/_shortcuts.py +7 -1
  79. sempy_labs/migration/_direct_lake_to_import.py +2 -0
  80. sempy_labs/mirrored_azure_databricks_catalog/__init__.py +15 -0
  81. sempy_labs/mirrored_azure_databricks_catalog/_discover.py +213 -0
  82. sempy_labs/mirrored_azure_databricks_catalog/_refresh_catalog_metadata.py +45 -0
  83. sempy_labs/report/_download_report.py +2 -1
  84. sempy_labs/report/_generate_report.py +2 -0
  85. sempy_labs/report/_paginated.py +2 -0
  86. sempy_labs/report/_report_bpa.py +110 -122
  87. sempy_labs/report/_report_bpa_rules.py +2 -0
  88. sempy_labs/report/_report_functions.py +7 -0
  89. sempy_labs/report/_reportwrapper.py +86 -48
  90. sempy_labs/theme/__init__.py +12 -0
  91. sempy_labs/theme/_org_themes.py +96 -0
  92. sempy_labs/tom/_model.py +702 -35
  93. {semantic_link_labs-0.10.0.dist-info → semantic_link_labs-0.11.0.dist-info}/WHEEL +0 -0
  94. {semantic_link_labs-0.10.0.dist-info → semantic_link_labs-0.11.0.dist-info}/licenses/LICENSE +0 -0
  95. {semantic_link_labs-0.10.0.dist-info → semantic_link_labs-0.11.0.dist-info}/top_level.txt +0 -0
@@ -9,8 +9,10 @@ from sempy_labs._helper_functions import (
9
9
  )
10
10
  from uuid import UUID
11
11
  import sempy_labs._icons as icons
12
+ from sempy._utils._log import log
12
13
 
13
14
 
15
+ @log
14
16
  def list_datasets(
15
17
  top: Optional[int] = None,
16
18
  filter: Optional[str] = None,
@@ -77,46 +79,45 @@ def list_datasets(
77
79
  url = _build_url(url, params)
78
80
  response = _base_api(request=url, client="fabric_sp")
79
81
 
80
- rows = []
82
+ dfs = []
81
83
  for v in response.json().get("value", []):
82
- rows.append(
83
- {
84
- "Dataset Id": v.get("id"),
85
- "Dataset Name": v.get("name"),
86
- "Web URL": v.get("webUrl"),
87
- "Add Rows API Enabled": v.get("addRowsAPIEnabled"),
88
- "Configured By": v.get("configuredBy"),
89
- "Is Refreshable": v.get("isRefreshable"),
90
- "Is Effective Identity Required": v.get("isEffectiveIdentityRequired"),
91
- "Is Effective Identity Roles Required": v.get(
92
- "isEffectiveIdentityRolesRequired"
93
- ),
94
- "Target Storage Mode": v.get("targetStorageMode"),
95
- "Created Date": pd.to_datetime(v.get("createdDate")),
96
- "Content Provider Type": v.get("contentProviderType"),
97
- "Create Report Embed URL": v.get("createReportEmbedURL"),
98
- "QnA Embed URL": v.get("qnaEmbedURL"),
99
- "Upstream Datasets": v.get("upstreamDatasets", []),
100
- "Users": v.get("users", []),
101
- "Is In Place Sharing Enabled": v.get("isInPlaceSharingEnabled"),
102
- "Workspace Id": v.get("workspaceId"),
103
- "Auto Sync Read Only Replicas": v.get("queryScaleOutSettings", {}).get(
104
- "autoSyncReadOnlyReplicas"
105
- ),
106
- "Max Read Only Replicas": v.get("queryScaleOutSettings", {}).get(
107
- "maxReadOnlyReplicas"
108
- ),
109
- }
110
- )
111
-
112
- if rows:
113
- df = pd.DataFrame(rows, columns=list(columns.keys()))
114
-
115
- _update_dataframe_datatypes(dataframe=df, column_map=columns)
84
+ new_data = {
85
+ "Dataset Id": v.get("id"),
86
+ "Dataset Name": v.get("name"),
87
+ "Web URL": v.get("webUrl"),
88
+ "Add Rows API Enabled": v.get("addRowsAPIEnabled"),
89
+ "Configured By": v.get("configuredBy"),
90
+ "Is Refreshable": v.get("isRefreshable"),
91
+ "Is Effective Identity Required": v.get("isEffectiveIdentityRequired"),
92
+ "Is Effective Identity Roles Required": v.get(
93
+ "isEffectiveIdentityRolesRequired"
94
+ ),
95
+ "Target Storage Mode": v.get("targetStorageMode"),
96
+ "Created Date": pd.to_datetime(v.get("createdDate")),
97
+ "Content Provider Type": v.get("contentProviderType"),
98
+ "Create Report Embed URL": v.get("createReportEmbedURL"),
99
+ "QnA Embed URL": v.get("qnaEmbedURL"),
100
+ "Upstream Datasets": v.get("upstreamDatasets", []),
101
+ "Users": v.get("users", []),
102
+ "Is In Place Sharing Enabled": v.get("isInPlaceSharingEnabled"),
103
+ "Workspace Id": v.get("workspaceId"),
104
+ "Auto Sync Read Only Replicas": v.get("queryScaleOutSettings", {}).get(
105
+ "autoSyncReadOnlyReplicas"
106
+ ),
107
+ "Max Read Only Replicas": v.get("queryScaleOutSettings", {}).get(
108
+ "maxReadOnlyReplicas"
109
+ ),
110
+ }
111
+ dfs.append(pd.DataFrame(new_data, index=[0]))
112
+
113
+ if dfs:
114
+ df = pd.concat(dfs, ignore_index=True)
115
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
116
116
 
117
117
  return df
118
118
 
119
119
 
120
+ @log
120
121
  def _resolve_dataset_id(dataset: str | UUID) -> str:
121
122
  if _is_valid_uuid(dataset):
122
123
  return dataset
@@ -128,6 +129,7 @@ def _resolve_dataset_id(dataset: str | UUID) -> str:
128
129
  return df_filt["Dataset Id"].iloc[0]
129
130
 
130
131
 
132
+ @log
131
133
  def list_dataset_users(dataset: str | UUID) -> pd.DataFrame:
132
134
  """
133
135
  Shows a list of users that have access to the specified dataset.
@@ -163,22 +165,20 @@ def list_dataset_users(dataset: str | UUID) -> pd.DataFrame:
163
165
  url = f"/v1.0/myorg/admin/datasets/{dataset_id}/users"
164
166
  response = _base_api(request=url, client="fabric_sp")
165
167
 
166
- rows = []
168
+ dfs = []
167
169
  for v in response.json().get("value", []):
168
- rows.append(
169
- {
170
- "User Name": v.get("displayName"),
171
- "Email Address": v.get("emailAddress"),
172
- "Dataset User Access Right": v.get("datasetUserAccessRight"),
173
- "Identifier": v.get("identifier"),
174
- "Graph Id": v.get("graphId"),
175
- "Principal Type": v.get("principalType"),
176
- }
177
- )
178
-
179
- if rows:
180
- df = pd.DataFrame(rows, columns=list(columns.keys()))
181
-
182
- _update_dataframe_datatypes(dataframe=df, column_map=columns)
170
+ new_data = {
171
+ "User Name": v.get("displayName"),
172
+ "Email Address": v.get("emailAddress"),
173
+ "Dataset User Access Right": v.get("datasetUserAccessRight"),
174
+ "Identifier": v.get("identifier"),
175
+ "Graph Id": v.get("graphId"),
176
+ "Principal Type": v.get("principalType"),
177
+ }
178
+ dfs.append(pd.DataFrame(new_data, index=[0]))
179
+
180
+ if dfs:
181
+ df = pd.concat(dfs, ignore_index=True)
182
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
183
183
 
184
184
  return df
@@ -8,8 +8,10 @@ from sempy_labs._helper_functions import (
8
8
  _create_dataframe,
9
9
  _is_valid_uuid,
10
10
  )
11
+ from sempy._utils._log import log
11
12
 
12
13
 
14
+ @log
13
15
  def resolve_domain_id(domain: Optional[str | UUID] = None, **kwargs) -> UUID:
14
16
  """
15
17
  Obtains the domain Id for a given domain name.
@@ -45,6 +47,7 @@ def resolve_domain_id(domain: Optional[str | UUID] = None, **kwargs) -> UUID:
45
47
  return dfL_filt["Domain ID"].iloc[0]
46
48
 
47
49
 
50
+ @log
48
51
  def resolve_domain_name(domain: Optional[str | UUID], **kwargs) -> UUID:
49
52
  """
50
53
  Obtains the domain name for a given domain ID.
@@ -80,6 +83,7 @@ def resolve_domain_name(domain: Optional[str | UUID], **kwargs) -> UUID:
80
83
  return dfL_filt["Domain Name"].iloc[0]
81
84
 
82
85
 
86
+ @log
83
87
  def list_domains(non_empty_only: bool = False) -> pd.DataFrame:
84
88
  """
85
89
  Shows a list of domains.
@@ -115,6 +119,7 @@ def list_domains(non_empty_only: bool = False) -> pd.DataFrame:
115
119
 
116
120
  response = _base_api(request=url, client="fabric_sp")
117
121
 
122
+ dfs = []
118
123
  for v in response.json().get("domains", []):
119
124
  new_data = {
120
125
  "Domain ID": v.get("id"),
@@ -123,11 +128,15 @@ def list_domains(non_empty_only: bool = False) -> pd.DataFrame:
123
128
  "Parent Domain ID": v.get("parentDomainId"),
124
129
  "Contributors Scope": v.get("contributorsScope"),
125
130
  }
126
- df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
131
+ dfs.append(pd.DataFrame(new_data, index=[0]))
132
+
133
+ if dfs:
134
+ df = pd.concat(dfs, ignore_index=True)
127
135
 
128
136
  return df
129
137
 
130
138
 
139
+ @log
131
140
  def list_domain_workspaces(domain: Optional[str] = None, **kwargs) -> pd.DataFrame:
132
141
  """
133
142
  Shows a list of workspaces within the domain.
@@ -178,6 +187,7 @@ def list_domain_workspaces(domain: Optional[str] = None, **kwargs) -> pd.DataFra
178
187
  return df
179
188
 
180
189
 
190
+ @log
181
191
  def create_domain(
182
192
  domain_name: str,
183
193
  description: Optional[str] = None,
@@ -222,6 +232,7 @@ def create_domain(
222
232
  print(f"{icons.green_dot} The '{domain_name}' domain has been created.")
223
233
 
224
234
 
235
+ @log
225
236
  def delete_domain(domain: Optional[str | UUID], **kwargs):
226
237
  """
227
238
  Deletes a domain.
@@ -249,6 +260,7 @@ def delete_domain(domain: Optional[str | UUID], **kwargs):
249
260
  print(f"{icons.green_dot} The '{domain}' domain has been deleted.")
250
261
 
251
262
 
263
+ @log
252
264
  def update_domain(
253
265
  domain: Optional[str | UUID] = None,
254
266
  description: Optional[str] = None,
@@ -301,6 +313,7 @@ def update_domain(
301
313
  print(f"{icons.green_dot} The '{domain_name}' domain has been updated.")
302
314
 
303
315
 
316
+ @log
304
317
  def assign_domain_workspaces_by_capacities(
305
318
  domain: str | UUID,
306
319
  capacity_names: str | List[str],
@@ -369,6 +382,7 @@ def assign_domain_workspaces_by_capacities(
369
382
  )
370
383
 
371
384
 
385
+ @log
372
386
  def assign_domain_workspaces(domain: str | UUID, workspace_names: str | List[str]):
373
387
  """
374
388
  Assigns workspaces to the specified domain by workspace.
@@ -420,6 +434,7 @@ def assign_domain_workspaces(domain: str | UUID, workspace_names: str | List[str
420
434
  )
421
435
 
422
436
 
437
+ @log
423
438
  def unassign_all_domain_workspaces(domain: str | UUID):
424
439
  """
425
440
  Unassigns all workspaces from the specified domain.
@@ -446,6 +461,7 @@ def unassign_all_domain_workspaces(domain: str | UUID):
446
461
  )
447
462
 
448
463
 
464
+ @log
449
465
  def unassign_domain_workspaces(
450
466
  domain: str | UUID,
451
467
  workspace_names: str | List[str],
@@ -7,8 +7,10 @@ from sempy_labs._helper_functions import (
7
7
  _create_dataframe,
8
8
  _update_dataframe_datatypes,
9
9
  )
10
+ from sempy._utils._log import log
10
11
 
11
12
 
13
+ @log
12
14
  def list_external_data_shares() -> pd.DataFrame:
13
15
  """
14
16
  Lists external data shares in the tenant. This function is for admins.
@@ -39,6 +41,7 @@ def list_external_data_shares() -> pd.DataFrame:
39
41
 
40
42
  response = _base_api(request="/v1/admin/items/externalDataShares")
41
43
 
44
+ dfs = []
42
45
  for i in response.json().get("value", []):
43
46
  cp = i.get("creatorPrincipal", {})
44
47
  new_data = {
@@ -56,13 +59,16 @@ def list_external_data_shares() -> pd.DataFrame:
56
59
  "Invitation URL": i.get("invitationUrl"),
57
60
  }
58
61
 
59
- df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
62
+ dfs.append(pd.DataFrame(new_data, index=[0]))
60
63
 
61
- _update_dataframe_datatypes(dataframe=df, column_map=columns)
64
+ if dfs:
65
+ df = pd.concat(dfs, ignore_index=True)
66
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
62
67
 
63
68
  return df
64
69
 
65
70
 
71
+ @log
66
72
  def revoke_external_data_share(
67
73
  external_data_share_id: UUID, item_id: UUID, workspace: str | UUID
68
74
  ):
sempy_labs/admin/_git.py CHANGED
@@ -4,8 +4,10 @@ from sempy_labs._helper_functions import (
4
4
  )
5
5
  import pandas as pd
6
6
  from sempy_labs.admin._basic_functions import list_workspaces
7
+ from sempy._utils._log import log
7
8
 
8
9
 
10
+ @log
9
11
  def list_git_connections() -> pd.DataFrame:
10
12
  """
11
13
  Shows a list of Git connections.
@@ -38,6 +40,7 @@ def list_git_connections() -> pd.DataFrame:
38
40
  uses_pagination=True,
39
41
  )
40
42
 
43
+ dfs = []
41
44
  for r in responses:
42
45
  for v in r.get("value", []):
43
46
  git = v.get("gitProviderDetails", {})
@@ -52,16 +55,18 @@ def list_git_connections() -> pd.DataFrame:
52
55
  "Directory Name": git.get("directoryName"),
53
56
  }
54
57
 
55
- df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
58
+ dfs.append(pd.DataFrame(new_data, index=[0]))
56
59
 
57
- dfW = list_workspaces()
58
- df = pd.merge(
59
- df, dfW[["Id", "Name"]], left_on="Workspace Id", right_on="Id", how="left"
60
- )
61
- new_col_name = "Workspace Name"
62
- df = df.rename(columns={"Name": new_col_name})
63
- df.insert(1, new_col_name, df.pop(new_col_name))
60
+ if dfs:
61
+ df = pd.concat(dfs, ignore_index=True)
62
+ dfW = list_workspaces()
63
+ df = pd.merge(
64
+ df, dfW[["Id", "Name"]], left_on="Workspace Id", right_on="Id", how="left"
65
+ )
66
+ new_col_name = "Workspace Name"
67
+ df = df.rename(columns={"Name": new_col_name})
68
+ df.insert(1, new_col_name, df.pop(new_col_name))
64
69
 
65
- df = df.drop(columns=["Id"])
70
+ df = df.drop(columns=["Id"])
66
71
 
67
72
  return df
@@ -14,8 +14,10 @@ from sempy_labs._helper_functions import (
14
14
  _base_api,
15
15
  _create_dataframe,
16
16
  )
17
+ from sempy._utils._log import log
17
18
 
18
19
 
20
+ @log
19
21
  def _resolve_item_id(
20
22
  item: str,
21
23
  type: Optional[str] = None,
@@ -39,6 +41,7 @@ def _resolve_item_id(
39
41
  return item_id
40
42
 
41
43
 
44
+ @log
42
45
  def _resolve_item_name_and_id(
43
46
  item: str,
44
47
  type: Optional[str] = None,
@@ -70,6 +73,7 @@ def _resolve_item_name_and_id(
70
73
  return item_name, item_id
71
74
 
72
75
 
76
+ @log
73
77
  def list_items(
74
78
  capacity: Optional[str | UUID] = None,
75
79
  workspace: Optional[str | UUID] = None,
@@ -146,6 +150,7 @@ def list_items(
146
150
 
147
151
  responses = _base_api(request=url, client="fabric_sp", uses_pagination=True)
148
152
 
153
+ dfs = []
149
154
  for r in responses:
150
155
  for v in r.get("itemEntities", []):
151
156
  new_data = {
@@ -166,7 +171,10 @@ def list_items(
166
171
  "Workspace Id": v.get("workspaceId"),
167
172
  "Capacity Id": v.get("capacityId"),
168
173
  }
169
- df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
174
+ dfs.append(pd.DataFrame(new_data, index=[0]))
175
+
176
+ if dfs:
177
+ df = pd.concat(dfs, ignore_index=True)
170
178
 
171
179
  if item is not None:
172
180
  if _is_valid_uuid(item):
@@ -177,6 +185,7 @@ def list_items(
177
185
  return df
178
186
 
179
187
 
188
+ @log
180
189
  def list_item_access_details(
181
190
  item: str | UUID = None,
182
191
  type: str = None,
@@ -241,6 +250,7 @@ def list_item_access_details(
241
250
  client="fabric_sp",
242
251
  )
243
252
 
253
+ dfs = []
244
254
  for v in response.json().get("accessDetails", []):
245
255
  new_data = {
246
256
  "User Id": v.get("principal", {}).get("id"),
@@ -257,6 +267,9 @@ def list_item_access_details(
257
267
  "Item Name": item_name,
258
268
  "Item Id": item_id,
259
269
  }
260
- df = pd.concat([df, pd.DataFrame([new_data])], ignore_index=True)
270
+ dfs.append(pd.DataFrame(new_data, index=[0]))
271
+
272
+ if dfs:
273
+ df = pd.concat(dfs, ignore_index=True)
261
274
 
262
275
  return df
@@ -8,8 +8,10 @@ from sempy_labs._helper_functions import (
8
8
  )
9
9
  from uuid import UUID
10
10
  import sempy_labs._icons as icons
11
+ from sempy._utils._log import log
11
12
 
12
13
 
14
+ @log
13
15
  def list_reports(
14
16
  top: Optional[int] = None,
15
17
  skip: Optional[int] = None,
@@ -67,37 +69,36 @@ def list_reports(
67
69
 
68
70
  url.rstrip("$").rstrip("?")
69
71
  response = _base_api(request=url, client="fabric_sp")
70
- rows = []
71
72
 
73
+ dfs = []
72
74
  for v in response.json().get("value", []):
73
- rows.append(
74
- {
75
- "Report Id": v.get("id"),
76
- "Report Name": v.get("name"),
77
- "Type": v.get("reportType"),
78
- "Web URL": v.get("webUrl"),
79
- "Embed URL": v.get("embedUrl"),
80
- "Dataset Id": v.get("datasetId"),
81
- "Created Date": v.get("createdDateTime"),
82
- "Modified Date": v.get("modifiedDateTime"),
83
- "Created By": v.get("createdBy"),
84
- "Modified By": v.get("modifiedBy"),
85
- "Sensitivity Label Id": v.get("sensitivityLabel", {}).get("labelId"),
86
- "Users": v.get("users"),
87
- "Subscriptions": v.get("subscriptions"),
88
- "Workspace Id": v.get("workspaceId"),
89
- "Report Flags": v.get("reportFlags"),
90
- }
91
- )
92
-
93
- if rows:
94
- df = pd.DataFrame(rows, columns=list(columns.keys()))
95
-
96
- _update_dataframe_datatypes(dataframe=df, column_map=columns)
75
+ new_data = {
76
+ "Report Id": v.get("id"),
77
+ "Report Name": v.get("name"),
78
+ "Type": v.get("reportType"),
79
+ "Web URL": v.get("webUrl"),
80
+ "Embed URL": v.get("embedUrl"),
81
+ "Dataset Id": v.get("datasetId"),
82
+ "Created Date": v.get("createdDateTime"),
83
+ "Modified Date": v.get("modifiedDateTime"),
84
+ "Created By": v.get("createdBy"),
85
+ "Modified By": v.get("modifiedBy"),
86
+ "Sensitivity Label Id": v.get("sensitivityLabel", {}).get("labelId"),
87
+ "Users": v.get("users"),
88
+ "Subscriptions": v.get("subscriptions"),
89
+ "Workspace Id": v.get("workspaceId"),
90
+ "Report Flags": v.get("reportFlags"),
91
+ }
92
+ dfs.append(pd.DataFrame(new_data, index=[0]))
93
+
94
+ if dfs:
95
+ df = pd.concat(dfs, ignore_index=True)
96
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
97
97
 
98
98
  return df
99
99
 
100
100
 
101
+ @log
101
102
  def _resolve_report_id(report: str | UUID) -> str:
102
103
  if _is_valid_uuid(report):
103
104
  return report
@@ -109,6 +110,7 @@ def _resolve_report_id(report: str | UUID) -> str:
109
110
  return df_filt["Report Id"].iloc[0]
110
111
 
111
112
 
113
+ @log
112
114
  def list_report_users(report: str | UUID) -> pd.DataFrame:
113
115
  """
114
116
  Shows a list of users that have access to the specified report.
@@ -144,27 +146,26 @@ def list_report_users(report: str | UUID) -> pd.DataFrame:
144
146
  url = f"/v1.0/myorg/admin/reports/{report_id}/users"
145
147
  response = _base_api(request=url, client="fabric_sp")
146
148
 
147
- rows = []
149
+ dfs = []
148
150
  for v in response.json().get("value", []):
149
- rows.append(
150
- {
151
- "User Name": v.get("displayName"),
152
- "Email Address": v.get("emailAddress"),
153
- "Report User Access Right": v.get("reportUserAccessRight"),
154
- "Identifier": v.get("identifier"),
155
- "Graph Id": v.get("graphId"),
156
- "Principal Type": v.get("principalType"),
157
- }
158
- )
159
-
160
- if rows:
161
- df = pd.DataFrame(rows, columns=list(columns.keys()))
162
-
163
- _update_dataframe_datatypes(dataframe=df, column_map=columns)
151
+ new_data = {
152
+ "User Name": v.get("displayName"),
153
+ "Email Address": v.get("emailAddress"),
154
+ "Report User Access Right": v.get("reportUserAccessRight"),
155
+ "Identifier": v.get("identifier"),
156
+ "Graph Id": v.get("graphId"),
157
+ "Principal Type": v.get("principalType"),
158
+ }
159
+ dfs.append(pd.DataFrame(new_data, index=[0]))
160
+
161
+ if dfs:
162
+ df = pd.concat(dfs, ignore_index=True)
163
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
164
164
 
165
165
  return df
166
166
 
167
167
 
168
+ @log
168
169
  def list_report_subscriptions(report: str | UUID) -> pd.DataFrame:
169
170
  """
170
171
  Shows a list of report subscriptions along with subscriber details. This is a preview API call.
@@ -210,30 +211,28 @@ def list_report_subscriptions(report: str | UUID) -> pd.DataFrame:
210
211
  client="fabric_sp",
211
212
  )
212
213
 
213
- rows = []
214
+ dfs = []
214
215
  for v in response.json().get("value", []):
215
- rows.append(
216
- {
217
- "Subscription Id": v.get("id"),
218
- "Title": v.get("title"),
219
- "Artifact Id": v.get("artifactId"),
220
- "Artifact Name": v.get("artifactDisplayName"),
221
- "Sub Artifact Name": v.get("subArtifactDisplayName"),
222
- "Artifact Type": v.get("artifactType"),
223
- "Is Enabled": v.get("isEnabled"),
224
- "Frequency": v.get("frequency"),
225
- "Start Date": v.get("startDate"),
226
- "End Date": v.get("endDate"),
227
- "Link To Content": v.get("linkToContent"),
228
- "Preview Image": v.get("previewImage"),
229
- "Attachment Format": v.get("attachmentFormat"),
230
- "Users": str(v.get("users")),
231
- }
232
- )
233
-
234
- if rows:
235
- df = pd.DataFrame(rows, columns=list(columns.keys()))
236
-
237
- _update_dataframe_datatypes(dataframe=df, column_map=columns)
216
+ new_data = {
217
+ "Subscription Id": v.get("id"),
218
+ "Title": v.get("title"),
219
+ "Artifact Id": v.get("artifactId"),
220
+ "Artifact Name": v.get("artifactDisplayName"),
221
+ "Sub Artifact Name": v.get("subArtifactDisplayName"),
222
+ "Artifact Type": v.get("artifactType"),
223
+ "Is Enabled": v.get("isEnabled"),
224
+ "Frequency": v.get("frequency"),
225
+ "Start Date": v.get("startDate"),
226
+ "End Date": v.get("endDate"),
227
+ "Link To Content": v.get("linkToContent"),
228
+ "Preview Image": v.get("previewImage"),
229
+ "Attachment Format": v.get("attachmentFormat"),
230
+ "Users": str(v.get("users")),
231
+ }
232
+ dfs.append(pd.DataFrame(new_data, index=[0]))
233
+
234
+ if dfs:
235
+ df = pd.concat(dfs, ignore_index=True)
236
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
238
237
 
239
238
  return df
@@ -3,8 +3,10 @@ from sempy_labs._helper_functions import (
3
3
  _base_api,
4
4
  _create_dataframe,
5
5
  )
6
+ from sempy._utils._log import log
6
7
 
7
8
 
9
+ @log
8
10
  def list_widely_shared_artifacts(
9
11
  api_name: str = "LinksSharedToWholeOrganization",
10
12
  ) -> pd.DataFrame:
@@ -55,6 +57,7 @@ def list_widely_shared_artifacts(
55
57
  uses_pagination=True,
56
58
  )
57
59
 
60
+ dfs = []
58
61
  for r in responses:
59
62
  for v in r.get("ArtifactAccessEntities", []):
60
63
  sharer = v.get("sharer", {})
@@ -71,6 +74,9 @@ def list_widely_shared_artifacts(
71
74
  "Sharer Principal Type": sharer.get("principalType"),
72
75
  }
73
76
 
74
- df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
77
+ dfs.append(pd.DataFrame(new_data, index=[0]))
78
+
79
+ if dfs:
80
+ df = pd.concat(dfs, ignore_index=True)
75
81
 
76
82
  return df
sempy_labs/admin/_tags.py CHANGED
@@ -6,8 +6,10 @@ from uuid import UUID
6
6
  from sempy_labs._tags import list_tags
7
7
  import sempy_labs._icons as icons
8
8
  from typing import List
9
+ from sempy._utils._log import log
9
10
 
10
11
 
12
+ @log
11
13
  def resolve_tag_id(tag: str | UUID):
12
14
 
13
15
  if _is_valid_uuid(tag):
@@ -22,6 +24,7 @@ def resolve_tag_id(tag: str | UUID):
22
24
  return tag_id
23
25
 
24
26
 
27
+ @log
25
28
  def create_tags(tags: str | List[str]):
26
29
  """
27
30
  Creates a new tag or tags.
@@ -77,6 +80,7 @@ def create_tags(tags: str | List[str]):
77
80
  print(f"{icons.green_dot} The '{available_tags}' tag(s) have been created.")
78
81
 
79
82
 
83
+ @log
80
84
  def delete_tag(tag: str | UUID):
81
85
  """
82
86
  Deletes a tag.
@@ -98,6 +102,7 @@ def delete_tag(tag: str | UUID):
98
102
  print(f"{icons.green_dot} The '{tag}' tag has been deleted.")
99
103
 
100
104
 
105
+ @log
101
106
  def update_tag(name: str, tag: str | UUID):
102
107
  """
103
108
  Updates the name of a tag.
@@ -38,6 +38,7 @@ def list_tenant_settings() -> pd.DataFrame:
38
38
 
39
39
  response = _base_api(request="/v1/admin/tenantsettings", client="fabric_sp")
40
40
 
41
+ dfs = []
41
42
  for i in response.json().get("value", []):
42
43
  new_data = {
43
44
  "Setting Name": i.get("settingName"),
@@ -47,9 +48,11 @@ def list_tenant_settings() -> pd.DataFrame:
47
48
  "Tenant Setting Group": i.get("tenantSettingGroup"),
48
49
  "Enabled Security Groups": [i.get("enabledSecurityGroups", [])],
49
50
  }
50
- df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
51
+ dfs.append(pd.DataFrame(new_data, index=[0]))
51
52
 
52
- _update_dataframe_datatypes(dataframe=df, column_map=columns)
53
+ if dfs:
54
+ df = pd.concat(dfs, ignore_index=True)
55
+ _update_dataframe_datatypes(dataframe=df, column_map=columns)
53
56
 
54
57
  return df
55
58