semantic-link-labs 0.11.3__py3-none-any.whl → 0.12.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.
- {semantic_link_labs-0.11.3.dist-info → semantic_link_labs-0.12.0.dist-info}/METADATA +5 -4
- {semantic_link_labs-0.11.3.dist-info → semantic_link_labs-0.12.0.dist-info}/RECORD +77 -73
- sempy_labs/__init__.py +6 -0
- sempy_labs/_a_lib_info.py +1 -1
- sempy_labs/_authentication.py +81 -32
- sempy_labs/_capacities.py +2 -2
- sempy_labs/_capacity_migration.py +4 -4
- sempy_labs/_clear_cache.py +1 -1
- sempy_labs/_connections.py +107 -70
- sempy_labs/_dashboards.py +6 -2
- sempy_labs/_data_pipelines.py +1 -1
- sempy_labs/_dataflows.py +1 -1
- sempy_labs/_dax.py +3 -3
- sempy_labs/_delta_analyzer.py +4 -4
- sempy_labs/_delta_analyzer_history.py +1 -1
- sempy_labs/_deployment_pipelines.py +1 -1
- sempy_labs/_environments.py +1 -1
- sempy_labs/_eventhouses.py +9 -3
- sempy_labs/_eventstreams.py +1 -1
- sempy_labs/_external_data_shares.py +1 -1
- sempy_labs/_gateways.py +14 -7
- sempy_labs/_generate_semantic_model.py +7 -12
- sempy_labs/_git.py +1 -1
- sempy_labs/_graphQL.py +1 -1
- sempy_labs/_helper_functions.py +161 -54
- sempy_labs/_job_scheduler.py +12 -1
- sempy_labs/_kql_databases.py +1 -1
- sempy_labs/_kql_querysets.py +10 -2
- sempy_labs/_kusto.py +2 -2
- sempy_labs/_list_functions.py +1 -1
- sempy_labs/_managed_private_endpoints.py +1 -1
- sempy_labs/_mirrored_databases.py +40 -16
- sempy_labs/_mirrored_warehouses.py +1 -1
- sempy_labs/_ml_experiments.py +1 -1
- sempy_labs/_model_bpa.py +6 -6
- sempy_labs/_model_bpa_bulk.py +3 -3
- sempy_labs/_model_dependencies.py +1 -1
- sempy_labs/_mounted_data_factories.py +3 -3
- sempy_labs/_notebooks.py +2 -1
- sempy_labs/_query_scale_out.py +2 -2
- sempy_labs/_refresh_semantic_model.py +1 -1
- sempy_labs/_semantic_models.py +15 -3
- sempy_labs/_spark.py +1 -1
- sempy_labs/_sql.py +3 -3
- sempy_labs/_sql_endpoints.py +5 -3
- sempy_labs/_sqldatabase.py +5 -1
- sempy_labs/_tags.py +3 -1
- sempy_labs/_translations.py +7 -360
- sempy_labs/_user_delegation_key.py +2 -2
- sempy_labs/_utils.py +27 -0
- sempy_labs/_vertipaq.py +3 -3
- sempy_labs/_vpax.py +1 -1
- sempy_labs/_warehouses.py +5 -0
- sempy_labs/_workloads.py +1 -1
- sempy_labs/_workspace_identity.py +1 -1
- sempy_labs/_workspaces.py +145 -11
- sempy_labs/admin/__init__.py +6 -0
- sempy_labs/admin/_capacities.py +34 -11
- sempy_labs/admin/_items.py +2 -2
- sempy_labs/admin/_tenant_keys.py +89 -0
- sempy_labs/directlake/_dl_helper.py +1 -1
- sempy_labs/lakehouse/__init__.py +4 -0
- sempy_labs/lakehouse/_materialized_lake_views.py +76 -0
- sempy_labs/lakehouse/_shortcuts.py +8 -2
- sempy_labs/report/_bpareporttemplate/.pbi/localSettings.json +9 -0
- sempy_labs/report/_bpareporttemplate/.platform +11 -0
- sempy_labs/report/_download_report.py +4 -1
- sempy_labs/report/_export_report.py +12 -5
- sempy_labs/report/_generate_report.py +11 -3
- sempy_labs/report/_paginated.py +21 -15
- sempy_labs/report/_report_functions.py +19 -11
- sempy_labs/report/_report_rebind.py +21 -10
- sempy_labs/theme/_org_themes.py +5 -6
- sempy_labs/tom/_model.py +5 -16
- {semantic_link_labs-0.11.3.dist-info → semantic_link_labs-0.12.0.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.11.3.dist-info → semantic_link_labs-0.12.0.dist-info}/licenses/LICENSE +0 -0
- {semantic_link_labs-0.11.3.dist-info → semantic_link_labs-0.12.0.dist-info}/top_level.txt +0 -0
sempy_labs/_workspaces.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
import sempy_labs._icons as icons
|
|
3
|
-
from typing import Optional
|
|
4
|
-
from ._helper_functions import (
|
|
3
|
+
from typing import Optional, Literal
|
|
4
|
+
from sempy_labs._helper_functions import (
|
|
5
|
+
resolve_workspace_id,
|
|
5
6
|
resolve_workspace_name_and_id,
|
|
6
7
|
resolve_capacity_id,
|
|
7
8
|
_base_api,
|
|
@@ -127,7 +128,7 @@ def list_workspace_users(workspace: Optional[str | UUID] = None) -> pd.DataFrame
|
|
|
127
128
|
A pandas dataframe the users of a workspace and their properties.
|
|
128
129
|
"""
|
|
129
130
|
|
|
130
|
-
|
|
131
|
+
workspace_id = resolve_workspace_id(workspace)
|
|
131
132
|
|
|
132
133
|
columns = {
|
|
133
134
|
"User Name": "string",
|
|
@@ -176,6 +177,8 @@ def add_user_to_workspace(
|
|
|
176
177
|
|
|
177
178
|
This is a wrapper function for the following API: `Groups - Add Group User <https://learn.microsoft.com/rest/api/power-bi/groups/add-group-user>`_.
|
|
178
179
|
|
|
180
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
181
|
+
|
|
179
182
|
Parameters
|
|
180
183
|
----------
|
|
181
184
|
email_address : str
|
|
@@ -217,6 +220,7 @@ def add_user_to_workspace(
|
|
|
217
220
|
request=f"/v1.0/myorg/groups/{workspace_id}/users",
|
|
218
221
|
method="post",
|
|
219
222
|
payload=payload,
|
|
223
|
+
client="fabric_sp",
|
|
220
224
|
)
|
|
221
225
|
print(
|
|
222
226
|
f"{icons.green_dot} The '{email_address}' user has been added as a{plural} '{role_name}' within the '{workspace_name}' workspace."
|
|
@@ -234,6 +238,8 @@ def assign_workspace_to_capacity(
|
|
|
234
238
|
|
|
235
239
|
This is a wrapper function for the following API: `Workspaces - Assign To Capacity <https://learn.microsoft.com/rest/api/fabric/core/workspaces/assign-to-capacity>`_.
|
|
236
240
|
|
|
241
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
242
|
+
|
|
237
243
|
Parameters
|
|
238
244
|
----------
|
|
239
245
|
capacity : str | uuid.UUID
|
|
@@ -260,6 +266,7 @@ def assign_workspace_to_capacity(
|
|
|
260
266
|
method="post",
|
|
261
267
|
payload=payload,
|
|
262
268
|
status_codes=[200, 202],
|
|
269
|
+
client="fabric_sp",
|
|
263
270
|
)
|
|
264
271
|
print(
|
|
265
272
|
f"{icons.green_dot} The '{workspace_name}' workspace has been assigned to the '{capacity}' capacity."
|
|
@@ -320,7 +327,7 @@ def list_workspace_role_assignments(
|
|
|
320
327
|
A pandas dataframe showing the members of a given workspace and their roles.
|
|
321
328
|
"""
|
|
322
329
|
|
|
323
|
-
|
|
330
|
+
workspace_id = resolve_workspace_id(workspace)
|
|
324
331
|
|
|
325
332
|
columns = {
|
|
326
333
|
"User Name": "string",
|
|
@@ -336,16 +343,23 @@ def list_workspace_role_assignments(
|
|
|
336
343
|
client="fabric_sp",
|
|
337
344
|
)
|
|
338
345
|
|
|
346
|
+
rows = []
|
|
339
347
|
for r in responses:
|
|
340
348
|
for i in r.get("value", []):
|
|
341
349
|
principal = i.get("principal", {})
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
350
|
+
rows.append(
|
|
351
|
+
{
|
|
352
|
+
"User Name": principal.get("displayName"),
|
|
353
|
+
"Role Name": i.get("role"),
|
|
354
|
+
"Type": principal.get("type"),
|
|
355
|
+
"User Email": principal.get("userDetails", {}).get(
|
|
356
|
+
"userPrincipalName"
|
|
357
|
+
),
|
|
358
|
+
}
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
if rows:
|
|
362
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
349
363
|
|
|
350
364
|
return df
|
|
351
365
|
|
|
@@ -357,6 +371,8 @@ def delete_workspace(workspace: Optional[str | UUID] = None):
|
|
|
357
371
|
|
|
358
372
|
This is a wrapper function for the following API: `Workspaces - Delete Workspace <https://learn.microsoft.com/rest/api/fabric/core/workspaces/delete-workspace>`_.
|
|
359
373
|
|
|
374
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
375
|
+
|
|
360
376
|
Parameters
|
|
361
377
|
----------
|
|
362
378
|
workspace : str | uuid.UUID, default=None
|
|
@@ -372,3 +388,121 @@ def delete_workspace(workspace: Optional[str | UUID] = None):
|
|
|
372
388
|
)
|
|
373
389
|
|
|
374
390
|
print(f"{icons.green_dot} The '{workspace_name}' workspace has been deleted.")
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
@log
|
|
394
|
+
def get_workspace_network_communication_policy(
|
|
395
|
+
workspace: Optional[str | UUID] = None,
|
|
396
|
+
) -> pd.DataFrame:
|
|
397
|
+
"""
|
|
398
|
+
Returns networking communication policy for the specified workspace. This feature is currently in preview.
|
|
399
|
+
|
|
400
|
+
This is a wrapper function for the following API: `Workspaces - Get Network Communication Policy <https://learn.microsoft.com/rest/api/fabric/core/workspaces/get-network-communication-policy>`_.
|
|
401
|
+
|
|
402
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
403
|
+
|
|
404
|
+
Parameters
|
|
405
|
+
----------
|
|
406
|
+
workspace : str | uuid.UUID, default=None
|
|
407
|
+
The workspace name or ID.
|
|
408
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
409
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
410
|
+
|
|
411
|
+
Returns
|
|
412
|
+
-------
|
|
413
|
+
pandas.DataFrame
|
|
414
|
+
A pandas dataframe showing the networking communication policy for the specified workspace.
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
workspace_id = resolve_workspace_id(workspace)
|
|
418
|
+
|
|
419
|
+
columns = {
|
|
420
|
+
"Inbound Public Access Rules": "string",
|
|
421
|
+
"Outbound Public Access Rules": "string",
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
df = _create_dataframe(columns=columns)
|
|
425
|
+
|
|
426
|
+
data = _base_api(
|
|
427
|
+
request=f"/v1/workspaces/{workspace_id}/networking/communicationPolicy",
|
|
428
|
+
client="fabric_sp",
|
|
429
|
+
).json()
|
|
430
|
+
|
|
431
|
+
if data:
|
|
432
|
+
df = pd.DataFrame(
|
|
433
|
+
[
|
|
434
|
+
{
|
|
435
|
+
"Inbound Public Access Rules": data.get("inbound", {})
|
|
436
|
+
.get("publicAccessRules", {})
|
|
437
|
+
.get("defaultAction"),
|
|
438
|
+
"Outbound Public Access Rules": data.get("outbound", {})
|
|
439
|
+
.get("publicAccessRules", {})
|
|
440
|
+
.get("defaultAction"),
|
|
441
|
+
}
|
|
442
|
+
]
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
return df
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
@log
|
|
449
|
+
def set_workspace_network_communication_policy(
|
|
450
|
+
inbound_policy: Literal["Allow", "Deny"],
|
|
451
|
+
outbound_policy: Literal["Allow", "Deny"],
|
|
452
|
+
workspace: Optional[str | UUID] = None,
|
|
453
|
+
):
|
|
454
|
+
"""
|
|
455
|
+
Sets networking communication policy for the specified workspace. This API uses the PUT method and will overwrite all settings. Remaining policy will be set to default value if only partial policy is provided in the request body. Always run Get Network Communication Policy first and provide full policy in the request body. This feature is currently in preview.
|
|
456
|
+
|
|
457
|
+
This is a wrapper function for the following API: `Workspaces - Set Network Communication Policy <https://learn.microsoft.com/rest/api/fabric/core/workspaces/set-network-communication-policy>`_.
|
|
458
|
+
|
|
459
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
460
|
+
|
|
461
|
+
Parameters
|
|
462
|
+
----------
|
|
463
|
+
inbound_policy : Literal['Allow', 'Deny']
|
|
464
|
+
The policy for all inbound communications to a workspace.
|
|
465
|
+
outbound_policy : Literal['Allow', 'Deny']
|
|
466
|
+
The policy for all outbound communications to a workspace.
|
|
467
|
+
workspace : str | uuid.UUID, default=None
|
|
468
|
+
The workspace name or ID.
|
|
469
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
470
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
471
|
+
"""
|
|
472
|
+
|
|
473
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
474
|
+
|
|
475
|
+
inbound_policy = inbound_policy.capitalize()
|
|
476
|
+
outbound_policy = outbound_policy.capitalize()
|
|
477
|
+
|
|
478
|
+
if inbound_policy not in ["Allow", "Deny"]:
|
|
479
|
+
raise ValueError(
|
|
480
|
+
f"{icons.red_dot} The 'inbound_policy' must be either 'Allow' or 'Deny'."
|
|
481
|
+
)
|
|
482
|
+
if outbound_policy not in ["Allow", "Deny"]:
|
|
483
|
+
raise ValueError(
|
|
484
|
+
f"{icons.red_dot} The 'outbound_policy' must be either 'Allow' or 'Deny'."
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
payload = {
|
|
488
|
+
"inbound": {
|
|
489
|
+
"publicAccessRules": {
|
|
490
|
+
"defaultAction": inbound_policy,
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
"outbound": {
|
|
494
|
+
"publicAccessRules": {
|
|
495
|
+
"defaultAction": outbound_policy,
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
}
|
|
499
|
+
_base_api(
|
|
500
|
+
request=f"/v1/workspaces/{workspace_id}/networking/communicationPolicy",
|
|
501
|
+
client="fabric_sp",
|
|
502
|
+
payload=payload,
|
|
503
|
+
method="put",
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
print(
|
|
507
|
+
f"{icons.green_dot} The networking communication policy has been updated for the '{workspace_name}' workspace."
|
|
508
|
+
)
|
sempy_labs/admin/__init__.py
CHANGED
|
@@ -90,6 +90,10 @@ from ._tags import (
|
|
|
90
90
|
create_tags,
|
|
91
91
|
delete_tag,
|
|
92
92
|
)
|
|
93
|
+
from ._tenant_keys import (
|
|
94
|
+
list_tenant_keys,
|
|
95
|
+
rotate_tenant_key,
|
|
96
|
+
)
|
|
93
97
|
|
|
94
98
|
__all__ = [
|
|
95
99
|
"list_items",
|
|
@@ -149,4 +153,6 @@ __all__ = [
|
|
|
149
153
|
"list_tags",
|
|
150
154
|
"create_tags",
|
|
151
155
|
"delete_tag",
|
|
156
|
+
"list_tenant_keys",
|
|
157
|
+
"rotate_tenant_key",
|
|
152
158
|
]
|
sempy_labs/admin/_capacities.py
CHANGED
|
@@ -3,7 +3,7 @@ from uuid import UUID
|
|
|
3
3
|
import sempy_labs._icons as icons
|
|
4
4
|
from typing import Optional, Tuple
|
|
5
5
|
from sempy._utils._log import log
|
|
6
|
-
from
|
|
6
|
+
from sempy_labs._helper_functions import (
|
|
7
7
|
_base_api,
|
|
8
8
|
_build_url,
|
|
9
9
|
_create_dataframe,
|
|
@@ -226,6 +226,7 @@ def get_capacity_state(capacity: Optional[str | UUID] = None):
|
|
|
226
226
|
@log
|
|
227
227
|
def list_capacities(
|
|
228
228
|
capacity: Optional[str | UUID] = None,
|
|
229
|
+
include_tenant_key: bool = False,
|
|
229
230
|
) -> pd.DataFrame:
|
|
230
231
|
"""
|
|
231
232
|
Shows the a list of capacities and their properties.
|
|
@@ -238,6 +239,8 @@ def list_capacities(
|
|
|
238
239
|
----------
|
|
239
240
|
capacity : str | uuid.UUID, default=None
|
|
240
241
|
The capacity name or ID to filter. If None, all capacities are returned.
|
|
242
|
+
include_tenant_key : bool, default=False
|
|
243
|
+
If True, obtains the `tenant key <https://learn.microsoft.com/rest/api/power-bi/admin/get-capacities-as-admin#example-with-expand-on-tenant-key>`_ properties.
|
|
241
244
|
|
|
242
245
|
Returns
|
|
243
246
|
-------
|
|
@@ -252,27 +255,47 @@ def list_capacities(
|
|
|
252
255
|
"Region": "string",
|
|
253
256
|
"State": "string",
|
|
254
257
|
"Admins": "list",
|
|
258
|
+
"Users": "list",
|
|
255
259
|
}
|
|
260
|
+
if include_tenant_key:
|
|
261
|
+
columns.update(
|
|
262
|
+
{
|
|
263
|
+
"Tenant Key Id": "string",
|
|
264
|
+
"Tenant Key Name": "string",
|
|
265
|
+
}
|
|
266
|
+
)
|
|
256
267
|
df = _create_dataframe(columns=columns)
|
|
257
268
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
269
|
+
url = "/v1.0/myorg/admin/capacities"
|
|
270
|
+
if include_tenant_key:
|
|
271
|
+
url += "?$expand=tenantKey"
|
|
272
|
+
|
|
273
|
+
responses = _base_api(request=url, client="fabric_sp", uses_pagination=True)
|
|
261
274
|
|
|
262
275
|
rows = []
|
|
263
276
|
for r in responses:
|
|
264
277
|
for i in r.get("value", []):
|
|
265
|
-
|
|
278
|
+
row = {
|
|
279
|
+
"Capacity Id": i.get("id", "").lower(),
|
|
280
|
+
"Capacity Name": i.get("displayName"),
|
|
281
|
+
"Sku": i.get("sku"),
|
|
282
|
+
"Region": i.get("region"),
|
|
283
|
+
"State": i.get("state"),
|
|
284
|
+
"Admins": i.get("admins", []),
|
|
285
|
+
"Users": i.get("users", []),
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if include_tenant_key:
|
|
289
|
+
tenant_key = i.get("tenantKey") or {}
|
|
290
|
+
row.update(
|
|
266
291
|
{
|
|
267
|
-
"
|
|
268
|
-
"
|
|
269
|
-
"Sku": i.get("sku"),
|
|
270
|
-
"Region": i.get("region"),
|
|
271
|
-
"State": i.get("state"),
|
|
272
|
-
"Admins": [i.get("admins", [])],
|
|
292
|
+
"Tenant Key Id": tenant_key.get("id"),
|
|
293
|
+
"Tenant Key Name": tenant_key.get("name"),
|
|
273
294
|
}
|
|
274
295
|
)
|
|
275
296
|
|
|
297
|
+
rows.append(row)
|
|
298
|
+
|
|
276
299
|
if rows:
|
|
277
300
|
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
278
301
|
|
sempy_labs/admin/_items.py
CHANGED
|
@@ -228,8 +228,8 @@ def list_item_access_details(
|
|
|
228
228
|
f"{icons.red_dot} The parameter 'item' and 'type' are mandatory."
|
|
229
229
|
)
|
|
230
230
|
|
|
231
|
-
workspace_name, workspace_id = _resolve_workspace_name_and_id(workspace)
|
|
232
|
-
item_name, item_id = _resolve_item_name_and_id(
|
|
231
|
+
(workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
|
|
232
|
+
(item_name, item_id) = _resolve_item_name_and_id(
|
|
233
233
|
item=item, type=type, workspace=workspace_name
|
|
234
234
|
)
|
|
235
235
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from sempy_labs._helper_functions import (
|
|
3
|
+
_create_dataframe,
|
|
4
|
+
_update_dataframe_datatypes,
|
|
5
|
+
_base_api,
|
|
6
|
+
)
|
|
7
|
+
from sempy._utils._log import log
|
|
8
|
+
from uuid import UUID
|
|
9
|
+
import sempy_labs._icons as icons
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@log
|
|
13
|
+
def list_tenant_keys() -> pd.DataFrame:
|
|
14
|
+
"""
|
|
15
|
+
Returns the encryption keys for the tenant.
|
|
16
|
+
|
|
17
|
+
This is a wrapper function for the following API: `Admin - Get Power BI Encryption Keys <https://learn.microsoft.com/rest/api/power-bi/admin/get-power-bi-encryption-keys>`_.
|
|
18
|
+
|
|
19
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
pandas.DataFrame
|
|
24
|
+
A pandas dataframe showing the encryption keys for the tenant.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
columns = {
|
|
28
|
+
"Tenant Key Id": "str",
|
|
29
|
+
"Tenant Key Name": "str",
|
|
30
|
+
"Key Vault Key Identifier": "str",
|
|
31
|
+
"Is Default": "bool",
|
|
32
|
+
"Created At": "datetime",
|
|
33
|
+
"Updated At": "datetime",
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
df = _create_dataframe(columns=columns)
|
|
37
|
+
|
|
38
|
+
result = _base_api(
|
|
39
|
+
request="/v1.0/myorg/admin/tenantKeys", client="fabric_sp"
|
|
40
|
+
).json()
|
|
41
|
+
|
|
42
|
+
rows = []
|
|
43
|
+
for i in result.get("value", []):
|
|
44
|
+
rows.append(
|
|
45
|
+
{
|
|
46
|
+
"Tenant Key Id": i.get("id"),
|
|
47
|
+
"Tenant Key Name": i.get("name"),
|
|
48
|
+
"Key Vault Key Identifier": i.get("keyVaultKeyIdentifier"),
|
|
49
|
+
"Is Default": i.get("isDefault"),
|
|
50
|
+
"Created At": i.get("createdAt"),
|
|
51
|
+
"Updated At": i.get("updatedAt"),
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
if rows:
|
|
56
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
57
|
+
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
58
|
+
|
|
59
|
+
return df
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@log
|
|
63
|
+
def rotate_tenant_key(tenant_key_id: UUID, key_vault_key_identifier: str):
|
|
64
|
+
"""
|
|
65
|
+
Rotate the encryption key for Power BI workspaces assigned to a capacity.
|
|
66
|
+
|
|
67
|
+
This is a wrapper function for the following API: `Admin - Rotate Power BI Encryption Key <https://learn.microsoft.com/rest/api/power-bi/admin/rotate-power-bi-encryption-key>`_.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
tenant_key_id : uuid.UUID
|
|
72
|
+
The tenant key ID
|
|
73
|
+
key_vault_key_identifier : str
|
|
74
|
+
The URI that uniquely specifies the encryption key in Azure Key Vault
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
payload = {
|
|
78
|
+
"keyVaultKeyIdentifier": key_vault_key_identifier,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
_base_api(
|
|
82
|
+
request=f"/v1.0/myorg/admin/tenantKeys/{tenant_key_id}/Default.Rotate",
|
|
83
|
+
method="post",
|
|
84
|
+
payload=payload,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
print(
|
|
88
|
+
f"{icons.green_dot} The encryption key for tenant {tenant_key_id} has been rotated successfully using the '{key_vault_key_identifier}' Key Vault key identifier."
|
|
89
|
+
)
|
|
@@ -145,7 +145,7 @@ def generate_direct_lake_semantic_model(
|
|
|
145
145
|
expr = generate_shared_expression(
|
|
146
146
|
item_name=lakehouse, item_type="Lakehouse", workspace=lakehouse_workspace
|
|
147
147
|
)
|
|
148
|
-
dfD = fabric.list_datasets(workspace=workspace_id)
|
|
148
|
+
dfD = fabric.list_datasets(workspace=workspace_id, mode="rest")
|
|
149
149
|
dfD_filt = dfD[dfD["Dataset Name"] == dataset]
|
|
150
150
|
|
|
151
151
|
if len(dfD_filt) > 0 and not overwrite:
|
sempy_labs/lakehouse/__init__.py
CHANGED
|
@@ -30,6 +30,9 @@ from ._helper import (
|
|
|
30
30
|
update_lakehouse,
|
|
31
31
|
load_table,
|
|
32
32
|
)
|
|
33
|
+
from ._materialized_lake_views import (
|
|
34
|
+
refresh_materialized_lake_views,
|
|
35
|
+
)
|
|
33
36
|
|
|
34
37
|
__all__ = [
|
|
35
38
|
"get_lakehouse_columns",
|
|
@@ -50,4 +53,5 @@ __all__ = [
|
|
|
50
53
|
"delete_lakehouse",
|
|
51
54
|
"update_lakehouse",
|
|
52
55
|
"load_table",
|
|
56
|
+
"refresh_materialized_lake_views",
|
|
53
57
|
]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from sempy_labs._helper_functions import (
|
|
3
|
+
resolve_workspace_name_and_id,
|
|
4
|
+
resolve_lakehouse_name_and_id,
|
|
5
|
+
_base_api,
|
|
6
|
+
)
|
|
7
|
+
from uuid import UUID
|
|
8
|
+
from sempy._utils._log import log
|
|
9
|
+
import sempy_labs._icons as icons
|
|
10
|
+
import time
|
|
11
|
+
from sempy_labs._job_scheduler import (
|
|
12
|
+
_get_item_job_instance,
|
|
13
|
+
)
|
|
14
|
+
import pandas as pd
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@log
|
|
18
|
+
def refresh_materialized_lake_views(
|
|
19
|
+
lakehouse: Optional[str | UUID] = None, workspace: Optional[str | UUID] = None
|
|
20
|
+
) -> pd.DataFrame:
|
|
21
|
+
"""
|
|
22
|
+
Run on-demand Refresh MaterializedLakeViews job instance.
|
|
23
|
+
|
|
24
|
+
This is a wrapper function for the following API: `Background Jobs - Run On Demand Refresh Materialized Lake Views <https://learn.microsoft.com/rest/api/fabric/lakehouse/background-jobs/run-on-demand-refresh-materialized-lake-views>`_.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
lakehouse : str | uuid.UUID, default=None
|
|
29
|
+
The Fabric lakehouse name or ID.
|
|
30
|
+
Defaults to None which resolves to the lakehouse attached to the notebook.
|
|
31
|
+
workspace : str | uuid.UUID, default=None
|
|
32
|
+
The Fabric workspace name or ID used by the lakehouse.
|
|
33
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
34
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
pandas.DataFrame
|
|
39
|
+
A DataFrame containing the job instance details of the refresh materialized lake views operation.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
43
|
+
(lakehouse_name, lakehouse_id) = resolve_lakehouse_name_and_id(
|
|
44
|
+
lakehouse=lakehouse, workspace=workspace_id
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
response = _base_api(
|
|
48
|
+
request=f"/v1/workspaces/{workspace_id}/lakehouses/{lakehouse_id}/jobs/instances?jobType=RefreshMaterializedLakeViews",
|
|
49
|
+
method="post",
|
|
50
|
+
status_codes=[202],
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
print(
|
|
54
|
+
f"{icons.in_progress} The refresh materialized lake views job for the '{lakehouse_name}' lakehouse within the '{workspace_name}' workspace has been initiated."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
status_url = response.headers.get("Location").split("fabric.microsoft.com")[1]
|
|
58
|
+
status = None
|
|
59
|
+
while status not in ["Completed", "Failed"]:
|
|
60
|
+
response = _base_api(request=status_url)
|
|
61
|
+
status = response.json().get("status")
|
|
62
|
+
time.sleep(3)
|
|
63
|
+
|
|
64
|
+
df = _get_item_job_instance(url=status_url)
|
|
65
|
+
|
|
66
|
+
if status == "Completed":
|
|
67
|
+
print(
|
|
68
|
+
f"{icons.green_dot} The refresh materialized lake views job for the '{lakehouse_name}' lakehouse within the '{workspace_name}' workspace has succeeded."
|
|
69
|
+
)
|
|
70
|
+
else:
|
|
71
|
+
print(status)
|
|
72
|
+
print(
|
|
73
|
+
f"{icons.red_dot} The refresh materialized lake views job for the '{lakehouse_name}' lakehouse within the '{workspace_name}' workspace has failed."
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
return df
|
|
@@ -2,6 +2,7 @@ import sempy.fabric as fabric
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
from .._helper_functions import (
|
|
4
4
|
resolve_lakehouse_name_and_id,
|
|
5
|
+
resolve_workspace_id,
|
|
5
6
|
resolve_workspace_name_and_id,
|
|
6
7
|
_base_api,
|
|
7
8
|
_create_dataframe,
|
|
@@ -268,6 +269,8 @@ def reset_shortcut_cache(workspace: Optional[str | UUID] = None):
|
|
|
268
269
|
|
|
269
270
|
This is a wrapper function for the following API: `OneLake Shortcuts - Reset Shortcut Cache <https://learn.microsoft.com/rest/api/fabric/core/onelake-shortcuts/reset-shortcut-cache>`_.
|
|
270
271
|
|
|
272
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
273
|
+
|
|
271
274
|
Parameters
|
|
272
275
|
----------
|
|
273
276
|
workspace : str | uuid.UUID, default=None
|
|
@@ -281,6 +284,7 @@ def reset_shortcut_cache(workspace: Optional[str | UUID] = None):
|
|
|
281
284
|
_base_api(
|
|
282
285
|
request=f"/v1/workspaces/{workspace_id}/onelake/resetShortcutCache",
|
|
283
286
|
method="post",
|
|
287
|
+
client="fabric_sp",
|
|
284
288
|
lro_return_status_code=True,
|
|
285
289
|
status_codes=None,
|
|
286
290
|
)
|
|
@@ -318,7 +322,7 @@ def list_shortcuts(
|
|
|
318
322
|
A pandas dataframe showing all the shortcuts which exist in the specified lakehouse.
|
|
319
323
|
"""
|
|
320
324
|
|
|
321
|
-
|
|
325
|
+
workspace_id = resolve_workspace_id(workspace)
|
|
322
326
|
(lakehouse_name, lakehouse_id) = resolve_lakehouse_name_and_id(
|
|
323
327
|
lakehouse=lakehouse, workspace=workspace_id
|
|
324
328
|
)
|
|
@@ -383,7 +387,9 @@ def list_shortcuts(
|
|
|
383
387
|
source_item_id = tgt.get(sources.get(tgt_type), {}).get("itemId")
|
|
384
388
|
bucket = tgt.get(sources.get(tgt_type), {}).get("bucket")
|
|
385
389
|
source_workspace_name = (
|
|
386
|
-
resolve_workspace_name(
|
|
390
|
+
resolve_workspace_name(
|
|
391
|
+
workspace_id=source_workspace_id, throw_error=False
|
|
392
|
+
)
|
|
387
393
|
if source_workspace_id is not None
|
|
388
394
|
else None
|
|
389
395
|
)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0",
|
|
3
|
+
"remoteArtifacts": [
|
|
4
|
+
{
|
|
5
|
+
"reportId": "6a91c344-dba8-4ebf-bedb-e07134f2a204"
|
|
6
|
+
}
|
|
7
|
+
],
|
|
8
|
+
"securityBindingsSignature": "AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAMAVu7l76YU6Sl11KOiJdgQAAAAACAAAAAAAQZgAAAAEAACAAAAD1Ty+c7tZLT9/Sjguxhn/5ivfLWfUMNtgudyJ3BKzzZgAAAAAOgAAAAAIAACAAAABAyGf+iKMwvmNtcoRczjgebeIm0nlc9SFYTBYv3N7yvVADAADQN3JsIsvJUcKKc9WMo2EhiE21odezpd35tb+yudHwA/RYhypMA3fwiCTwArLefBZQ3vZ7KYh4MjihXS07i9o1XVqxAmDoli83Yhs/Wei+0HIfYOT5HOVHLUEul5x41Yx/7Bdfhc881SK6IoaJogBdwsiJVxPne+niMYqJQA6qLEPyJ33g6ucUxLA40lwdbN2cMWFzRn6tymmicDPwH0hcGPDMWwseAU+OuUeidkneRWhUGs6lkiiXLiO6kmY5RKq+S4FdtR19/e1B6EjAd94zSw+M5jQzYxn4eCZzWYiB+8Zd/jy07lfyLoGwagNqiQzbcNONqQd5w0n+8/+n4zGkBi2UojfRXoGaYDirQeZMTbt3pfPx2PArxsJ8dF0iT634pHiCF1ZFdtY+79JaFLUUG+Yf7JJv8IxuuuF74tAp4NYmuOij4hTDaf8Jafa5IoRVh7ICkwrjJyVQ8dG7I3tr0VvR+toBPG3Zlbm9BijcaBxhh1AINhnRAIkENOnPFQVH7l3Ml7B60H8Tst6ic3ihCCMYjtmN+NNWqFrJKT2trilh5TAxN+ei4H5fPwM9S7zb2bH5jhExcYTtoe7iCzxOvBsoYoFM+7FMjn9R2FATNICktYdbKDo1Of+u4oZ1+RsvBHQBVaMhSCoZ7+K5T5pZayNK3V2UID3wOuLOYvouxXXr4NVFsdgiV2oMuxTWeqmd/4bLxeqe3uTkGFmQU4mumF2YVsNbdO3IcRXhhrCCZ27ffzXBsH+lE3EhusD37Z0dsVbVVlG8AHXCh7Atgd8n73/eSI5mvj36DCOSRBVauItIATIa2FXueKA7vU6lRDYBSX8FCC2qkeN6dWpMoN5uXXEBsb5Yot1Fgrovcyl5lk7rh772Xon4FaIYFHZpklsY3JK5EXp3bF8UOE6ByN1ZucmkGgYRcTT/up/Uc86TLN6env9XXL4FQYPlReiOGWKBLVi9OoXGRLDshspniULtV3EwQ6WsjF2AyQ+WdLj3bbWKzG5Mg9jvANLrjycZAGWskh4X5JDGiv4TiJmnYQ/xPZAKKiowpVIHikLeG76uXFI+bxtpihV9+DaEJy4UxisHQxwuvUsQs38u3SHgpJmT8CNssZl41+T/IJdoQwJFLUAAAACnUQZGV9DvcOyrj8HBpXBVB5PuOQDxLB4HZOevHqCB5dc5z787E93B51QmN7I15fF6GCdWwN5f94gv1er2dtN3"
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
|
|
3
|
+
"metadata": {
|
|
4
|
+
"type": "Report",
|
|
5
|
+
"displayName": "BPAReport"
|
|
6
|
+
},
|
|
7
|
+
"config": {
|
|
8
|
+
"version": "2.0",
|
|
9
|
+
"logicalId": "a201f2cd-fd25-465f-bfbc-33b151e38b31"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -25,6 +25,8 @@ def download_report(
|
|
|
25
25
|
|
|
26
26
|
This is a wrapper function for the following API: `Reports - Export Report In Group <https://learn.microsoft.com/rest/api/power-bi/reports/export-report-in-group>`_.
|
|
27
27
|
|
|
28
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
29
|
+
|
|
28
30
|
Parameters
|
|
29
31
|
----------
|
|
30
32
|
report: str | uuid.UUID
|
|
@@ -59,7 +61,8 @@ def download_report(
|
|
|
59
61
|
report_id = resolve_item_id(item=report, type="Report", workspace=workspace)
|
|
60
62
|
|
|
61
63
|
response = _base_api(
|
|
62
|
-
request=f"v1.0/myorg/groups/{workspace_id}/reports/{report_id}/Export?downloadType={download_type}"
|
|
64
|
+
request=f"v1.0/myorg/groups/{workspace_id}/reports/{report_id}/Export?downloadType={download_type}",
|
|
65
|
+
client="fabric_sp",
|
|
63
66
|
)
|
|
64
67
|
|
|
65
68
|
# Save file to the attached lakehouse
|
|
@@ -2,7 +2,7 @@ import sempy.fabric as fabric
|
|
|
2
2
|
import json
|
|
3
3
|
import os
|
|
4
4
|
import time
|
|
5
|
-
from
|
|
5
|
+
from sempy_labs._helper_functions import (
|
|
6
6
|
generate_embedded_filter,
|
|
7
7
|
resolve_workspace_name_and_id,
|
|
8
8
|
_base_api,
|
|
@@ -12,7 +12,7 @@ from typing import Optional
|
|
|
12
12
|
from sempy._utils._log import log
|
|
13
13
|
import sempy_labs._icons as icons
|
|
14
14
|
from uuid import UUID
|
|
15
|
-
from ._report_functions import (
|
|
15
|
+
from sempy_labs.report._report_functions import (
|
|
16
16
|
list_report_visuals,
|
|
17
17
|
list_report_pages,
|
|
18
18
|
)
|
|
@@ -36,6 +36,8 @@ def export_report(
|
|
|
36
36
|
|
|
37
37
|
This is a wrapper function for the following APIs: `Reports - Export To File In Group <https://learn.microsoft.com/rest/api/power-bi/reports/export-to-file-in-group>`_, `Reports - Get Export To File Status In Group <https://learn.microsoft.com/rest/api/power-bi/reports/get-export-to-file-status-in-group>`_, `Reports - Get File Of Export To File In Group <https://learn.microsoft.com/rest/api/power-bi/reports/get-file-of-export-to-file-in-group>`_.
|
|
38
38
|
|
|
39
|
+
Service Principal Authentication is supported (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
40
|
+
|
|
39
41
|
Parameters
|
|
40
42
|
----------
|
|
41
43
|
report : str
|
|
@@ -241,22 +243,27 @@ def export_report(
|
|
|
241
243
|
method="post",
|
|
242
244
|
payload=request_body,
|
|
243
245
|
status_codes=202,
|
|
246
|
+
client="fabric_sp",
|
|
244
247
|
)
|
|
245
248
|
export_id = json.loads(response.content).get("id")
|
|
246
249
|
|
|
247
250
|
get_status_url = f"{base_url}/exports/{export_id}"
|
|
248
|
-
response = _base_api(
|
|
251
|
+
response = _base_api(
|
|
252
|
+
request=get_status_url, status_codes=[200, 202], client="fabric_sp"
|
|
253
|
+
)
|
|
249
254
|
response_body = json.loads(response.content)
|
|
250
255
|
while response_body["status"] not in ["Succeeded", "Failed"]:
|
|
251
256
|
time.sleep(3)
|
|
252
|
-
response = _base_api(
|
|
257
|
+
response = _base_api(
|
|
258
|
+
request=get_status_url, status_codes=[200, 202], client="fabric_sp"
|
|
259
|
+
)
|
|
253
260
|
response_body = json.loads(response.content)
|
|
254
261
|
if response_body["status"] == "Failed":
|
|
255
262
|
raise ValueError(
|
|
256
263
|
f"{icons.red_dot} The export for the '{report}' report within the '{workspace_name}' workspace in the '{export_format}' format has failed."
|
|
257
264
|
)
|
|
258
265
|
else:
|
|
259
|
-
response = _base_api(request=f"{get_status_url}/file")
|
|
266
|
+
response = _base_api(request=f"{get_status_url}/file", client="fabric_sp")
|
|
260
267
|
print(
|
|
261
268
|
f"{icons.in_progress} Saving the '{export_format}' export for the '{report}' report within the '{workspace_name}' workspace to the lakehouse..."
|
|
262
269
|
)
|