semantic-link-labs 0.12.1__py3-none-any.whl → 0.12.3__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.12.1.dist-info → semantic_link_labs-0.12.3.dist-info}/METADATA +4 -2
- {semantic_link_labs-0.12.1.dist-info → semantic_link_labs-0.12.3.dist-info}/RECORD +32 -26
- sempy_labs/__init__.py +12 -0
- sempy_labs/_a_lib_info.py +1 -1
- sempy_labs/_data_access_security.py +98 -0
- sempy_labs/_data_pipelines.py +23 -9
- sempy_labs/_dataflows.py +0 -1
- sempy_labs/_deployment_pipelines.py +49 -27
- sempy_labs/_eventstreams.py +9 -1
- sempy_labs/_generate_semantic_model.py +2 -2
- sempy_labs/_get_connection_string.py +84 -0
- sempy_labs/_helper_functions.py +17 -1
- sempy_labs/_job_scheduler.py +63 -33
- sempy_labs/_labels.py +4 -6
- sempy_labs/_model_dependencies.py +5 -2
- sempy_labs/_semantic_models.py +118 -0
- sempy_labs/_sql_endpoints.py +12 -24
- sempy_labs/_warehouses.py +1 -1
- sempy_labs/admin/__init__.py +6 -0
- sempy_labs/admin/_sharing_links.py +110 -0
- sempy_labs/graph/__init__.py +16 -0
- sempy_labs/graph/_groups.py +157 -2
- sempy_labs/graph/_sensitivity_labels.py +81 -0
- sempy_labs/graph/_users.py +162 -0
- sempy_labs/lakehouse/_shortcuts.py +16 -11
- sempy_labs/report/_bpareporttemplate/.pbi/localSettings.json +9 -0
- sempy_labs/report/_bpareporttemplate/.platform +11 -0
- sempy_labs/report/_reportwrapper.py +53 -6
- sempy_labs/tom/_model.py +49 -18
- {semantic_link_labs-0.12.1.dist-info → semantic_link_labs-0.12.3.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.12.1.dist-info → semantic_link_labs-0.12.3.dist-info}/licenses/LICENSE +0 -0
- {semantic_link_labs-0.12.1.dist-info → semantic_link_labs-0.12.3.dist-info}/top_level.txt +0 -0
sempy_labs/graph/__init__.py
CHANGED
|
@@ -6,16 +6,25 @@ from ._groups import (
|
|
|
6
6
|
add_group_owners,
|
|
7
7
|
resolve_group_id,
|
|
8
8
|
renew_group,
|
|
9
|
+
create_group,
|
|
10
|
+
delete_group,
|
|
11
|
+
update_group,
|
|
9
12
|
)
|
|
10
13
|
from ._users import (
|
|
11
14
|
resolve_user_id,
|
|
12
15
|
get_user,
|
|
13
16
|
list_users,
|
|
14
17
|
send_mail,
|
|
18
|
+
create_user,
|
|
19
|
+
delete_user,
|
|
20
|
+
update_user,
|
|
15
21
|
)
|
|
16
22
|
from ._teams import (
|
|
17
23
|
list_teams,
|
|
18
24
|
)
|
|
25
|
+
from ._sensitivity_labels import (
|
|
26
|
+
list_sensitivity_labels,
|
|
27
|
+
)
|
|
19
28
|
|
|
20
29
|
__all__ = [
|
|
21
30
|
"list_groups",
|
|
@@ -30,4 +39,11 @@ __all__ = [
|
|
|
30
39
|
"list_users",
|
|
31
40
|
"send_mail",
|
|
32
41
|
"list_teams",
|
|
42
|
+
"create_user",
|
|
43
|
+
"create_group",
|
|
44
|
+
"delete_user",
|
|
45
|
+
"delete_group",
|
|
46
|
+
"update_user",
|
|
47
|
+
"update_group",
|
|
48
|
+
"list_sensitivity_labels",
|
|
33
49
|
]
|
sempy_labs/graph/_groups.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
from uuid import UUID
|
|
3
|
-
from
|
|
3
|
+
from sempy_labs._helper_functions import (
|
|
4
4
|
_is_valid_uuid,
|
|
5
5
|
_base_api,
|
|
6
6
|
_create_dataframe,
|
|
@@ -8,7 +8,7 @@ from .._helper_functions import (
|
|
|
8
8
|
)
|
|
9
9
|
from sempy._utils._log import log
|
|
10
10
|
import sempy_labs._icons as icons
|
|
11
|
-
from typing import List, Literal
|
|
11
|
+
from typing import List, Literal, Optional
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@log
|
|
@@ -424,3 +424,158 @@ def renew_group(group: str | UUID):
|
|
|
424
424
|
)
|
|
425
425
|
|
|
426
426
|
print(f"{icons.green_dot} The '{group}' group has been renewed.")
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
@log
|
|
430
|
+
def create_group(
|
|
431
|
+
display_name: str,
|
|
432
|
+
description: Optional[str] = None,
|
|
433
|
+
mail_enabled: bool = False,
|
|
434
|
+
security_enabled: bool = True,
|
|
435
|
+
mail_nickname: str = None,
|
|
436
|
+
owners: Optional[str | UUID | List[str | UUID]] = None,
|
|
437
|
+
members: Optional[str | UUID | List[str | UUID]] = None,
|
|
438
|
+
):
|
|
439
|
+
"""
|
|
440
|
+
Creates a new group.
|
|
441
|
+
|
|
442
|
+
This is a wrapper function for the following API: `Create group <https://learn.microsoft.com/graph/api/group-post-groups>`_.
|
|
443
|
+
|
|
444
|
+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
445
|
+
|
|
446
|
+
Parameters
|
|
447
|
+
----------
|
|
448
|
+
display_name : str
|
|
449
|
+
The name of the group.
|
|
450
|
+
description : str, optional
|
|
451
|
+
The description of the group.
|
|
452
|
+
mail_enabled : bool, default=False
|
|
453
|
+
Whether the group is mail-enabled.
|
|
454
|
+
security_enabled : bool, default=True
|
|
455
|
+
Whether the group is security-enabled.
|
|
456
|
+
mail_nickname : str, default=None
|
|
457
|
+
The mail alias for the group.
|
|
458
|
+
owners : str | uuid.UUID | List[str | uuid.UUID], default=None
|
|
459
|
+
The owners of the group.
|
|
460
|
+
members : str | uuid.UUID | List[str | uuid.UUID], default=None
|
|
461
|
+
The members of the group.
|
|
462
|
+
"""
|
|
463
|
+
from sempy_labs.graph._users import resolve_user_id
|
|
464
|
+
|
|
465
|
+
payload = {
|
|
466
|
+
"displayName": display_name,
|
|
467
|
+
"description": description,
|
|
468
|
+
"mailEnabled": mail_enabled,
|
|
469
|
+
"securityEnabled": security_enabled,
|
|
470
|
+
"mailNickname": mail_nickname,
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if owners:
|
|
474
|
+
if isinstance(owners, str):
|
|
475
|
+
owners = [owners]
|
|
476
|
+
user_list = []
|
|
477
|
+
for o in owners:
|
|
478
|
+
user_id = resolve_user_id(o)
|
|
479
|
+
user_list.append(f"https://graph.microsoft.com/v1.0/users/{user_id}")
|
|
480
|
+
payload["owners@odata.bind"] = user_list
|
|
481
|
+
if members:
|
|
482
|
+
if isinstance(members, str):
|
|
483
|
+
members = [members]
|
|
484
|
+
user_list = []
|
|
485
|
+
for m in members:
|
|
486
|
+
user_id = resolve_user_id(m)
|
|
487
|
+
user_list.append(f"https://graph.microsoft.com/v1.0/users/{user_id}")
|
|
488
|
+
payload["members@odata.bind"] = user_list
|
|
489
|
+
|
|
490
|
+
_base_api(
|
|
491
|
+
request="groups",
|
|
492
|
+
client="graph",
|
|
493
|
+
payload=payload,
|
|
494
|
+
method="post",
|
|
495
|
+
status_codes=201,
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
print(f"{icons.green_dot} The '{display_name}' group has been created.")
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
@log
|
|
502
|
+
def delete_group(group: str | UUID):
|
|
503
|
+
"""
|
|
504
|
+
Deletes a group.
|
|
505
|
+
|
|
506
|
+
This is a wrapper function for the following API: `Delete group <https://learn.microsoft.com/graph/api/group-delete>`_.
|
|
507
|
+
|
|
508
|
+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
509
|
+
|
|
510
|
+
Parameters
|
|
511
|
+
----------
|
|
512
|
+
group : str | uuid.UUID
|
|
513
|
+
The group name or ID.
|
|
514
|
+
"""
|
|
515
|
+
|
|
516
|
+
group_id = resolve_group_id(group)
|
|
517
|
+
|
|
518
|
+
_base_api(
|
|
519
|
+
request=f"groups/{group_id}",
|
|
520
|
+
client="graph",
|
|
521
|
+
status_codes=204,
|
|
522
|
+
method="delete",
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
print(f"{icons.green_dot} The '{group}' group has been deleted successfully.")
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
@log
|
|
529
|
+
def update_group(
|
|
530
|
+
group: str | UUID,
|
|
531
|
+
display_name: Optional[str] = None,
|
|
532
|
+
mail_nickname: Optional[str] = None,
|
|
533
|
+
description: Optional[str] = None,
|
|
534
|
+
security_enabled: Optional[bool] = None,
|
|
535
|
+
):
|
|
536
|
+
"""
|
|
537
|
+
Updates a group's properties.
|
|
538
|
+
|
|
539
|
+
This is a wrapper function for the following API: `Update group <https://learn.microsoft.com/en-us/graph/api/group-update>`_.
|
|
540
|
+
|
|
541
|
+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
542
|
+
|
|
543
|
+
Parameters
|
|
544
|
+
----------
|
|
545
|
+
group : str | uuid.UUID
|
|
546
|
+
The group name or ID.
|
|
547
|
+
display_name : str, default=None
|
|
548
|
+
The new display name for the group.
|
|
549
|
+
mail_nickname : str, default=None
|
|
550
|
+
The new mail nickname for the group.
|
|
551
|
+
description : str, default=None
|
|
552
|
+
The new description for the group.
|
|
553
|
+
security_enabled : bool, default=None
|
|
554
|
+
Whether the group is security-enabled.
|
|
555
|
+
"""
|
|
556
|
+
|
|
557
|
+
group_id = resolve_group_id(group)
|
|
558
|
+
|
|
559
|
+
payload = {}
|
|
560
|
+
if display_name:
|
|
561
|
+
payload["displayName"] = display_name
|
|
562
|
+
if mail_nickname:
|
|
563
|
+
payload["mailNickname"] = mail_nickname
|
|
564
|
+
if description:
|
|
565
|
+
payload["description"] = description
|
|
566
|
+
if security_enabled is not None and isinstance(security_enabled, bool):
|
|
567
|
+
payload["securityEnabled"] = security_enabled
|
|
568
|
+
|
|
569
|
+
if not payload:
|
|
570
|
+
print(f"{icons.info} No properties to update.")
|
|
571
|
+
return
|
|
572
|
+
|
|
573
|
+
_base_api(
|
|
574
|
+
request=f"groups/{group_id}",
|
|
575
|
+
client="graph",
|
|
576
|
+
status_codes=204,
|
|
577
|
+
payload=payload,
|
|
578
|
+
method="patch",
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
print(f"{icons.green_dot} The '{group}' group has been updated successfully.")
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from uuid import UUID
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from sempy_labs._helper_functions import (
|
|
5
|
+
_base_api,
|
|
6
|
+
_create_dataframe,
|
|
7
|
+
_update_dataframe_datatypes,
|
|
8
|
+
)
|
|
9
|
+
from sempy._utils._log import log
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@log
|
|
13
|
+
def list_sensitivity_labels(user: Optional[str | UUID] = None) -> pd.DataFrame:
|
|
14
|
+
"""
|
|
15
|
+
Get a list of `sensitivity label <https://learn.microsoft.com/graph/api/resources/security-sensitivitylabel>`_ objects associated with a user or organization.
|
|
16
|
+
|
|
17
|
+
This is a wrapper function for the following API: `List sensitivityLabels https://learn.microsoft.com/graph/api/security-informationprotection-list-sensitivitylabels>`_.
|
|
18
|
+
|
|
19
|
+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
user : str | uuid.UUID
|
|
24
|
+
The user ID or user principal name.
|
|
25
|
+
|
|
26
|
+
Returns
|
|
27
|
+
-------
|
|
28
|
+
pandas.DataFrame
|
|
29
|
+
A pandas dataframe showing a list of `sensitivity label <https://learn.microsoft.com/graph/api/resources/security-sensitivitylabel>`_ objects associated with a user or organization.
|
|
30
|
+
"""
|
|
31
|
+
from sempy_labs.graph import resolve_user_id
|
|
32
|
+
|
|
33
|
+
url = "/security/informationProtection/sensitivityLabels"
|
|
34
|
+
|
|
35
|
+
if user is not None:
|
|
36
|
+
user_id = resolve_user_id(user=user)
|
|
37
|
+
url = f"users/{user_id}{url}"
|
|
38
|
+
|
|
39
|
+
result = _base_api(request=url, client="graph").json()
|
|
40
|
+
|
|
41
|
+
columns = {
|
|
42
|
+
"Sensitivity Label Id": "str",
|
|
43
|
+
"Sensitivity Label Name": "str",
|
|
44
|
+
"Description": "str",
|
|
45
|
+
"Color": "str",
|
|
46
|
+
"Sensitivity": "int",
|
|
47
|
+
"Tooltip": "str",
|
|
48
|
+
"Is Active": "bool",
|
|
49
|
+
"Is Appliable": "bool",
|
|
50
|
+
"Has Protection": "bool",
|
|
51
|
+
"Parent Sensitivity Label Id": "str",
|
|
52
|
+
"Parent Sensitivity Label Name": "str",
|
|
53
|
+
}
|
|
54
|
+
df = _create_dataframe(columns=columns)
|
|
55
|
+
|
|
56
|
+
rows = []
|
|
57
|
+
for item in result.get("value", []):
|
|
58
|
+
row = {
|
|
59
|
+
"Sensitivity Label Id": item.get("id"),
|
|
60
|
+
"Sensitivity Label Name": item.get("name"),
|
|
61
|
+
"Description": item.get("description"),
|
|
62
|
+
"Color": item.get("color"),
|
|
63
|
+
"Sensitivity": item.get("sensitivity"),
|
|
64
|
+
"Tooltip": item.get("tooltip"),
|
|
65
|
+
"Is Active": item.get("isActive"),
|
|
66
|
+
"Is Appliable": item.get("isAppliable"),
|
|
67
|
+
"Has Protection": item.get("hasProtection"),
|
|
68
|
+
"Parent Sensitivity Label Id": (
|
|
69
|
+
item.get("parent", {}).get("id") if item.get("parent") else None
|
|
70
|
+
),
|
|
71
|
+
"Parent Sensitivity Label Name": (
|
|
72
|
+
item.get("parent", {}).get("name") if item.get("parent") else None
|
|
73
|
+
),
|
|
74
|
+
}
|
|
75
|
+
rows.append(row)
|
|
76
|
+
|
|
77
|
+
if rows:
|
|
78
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
79
|
+
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
80
|
+
|
|
81
|
+
return df
|
sempy_labs/graph/_users.py
CHANGED
|
@@ -301,3 +301,165 @@ def send_mail(
|
|
|
301
301
|
if attachments:
|
|
302
302
|
printout += f" with {len(attachments)} attachment(s)"
|
|
303
303
|
print(f"{printout}.")
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@log
|
|
307
|
+
def create_user(
|
|
308
|
+
display_name: str,
|
|
309
|
+
user_principal_name: str,
|
|
310
|
+
mail_nickname: str,
|
|
311
|
+
password: str,
|
|
312
|
+
account_enabled: bool = True,
|
|
313
|
+
force_change_password_next_sign_in: bool = True,
|
|
314
|
+
):
|
|
315
|
+
"""
|
|
316
|
+
Creates a new user.
|
|
317
|
+
|
|
318
|
+
This is a wrapper function for the following API: `Create User <https://learn.microsoft.com/graph/api/user-post-users>`_.
|
|
319
|
+
|
|
320
|
+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
321
|
+
|
|
322
|
+
Parameters
|
|
323
|
+
----------
|
|
324
|
+
display_name : str
|
|
325
|
+
The name to display in the address book for the user.
|
|
326
|
+
user_principal_name : str
|
|
327
|
+
The user principal name (someuser@contoso.com).
|
|
328
|
+
mail_nickname : str
|
|
329
|
+
The mail alias for the user.
|
|
330
|
+
password : str
|
|
331
|
+
The initial password for the user.
|
|
332
|
+
account_enabled : bool, default=True
|
|
333
|
+
Whether the account is enabled. Default is True.
|
|
334
|
+
force_change_password_next_sign_in : bool, default=True
|
|
335
|
+
Whether the user must change their password on next sign-in. Default is True.
|
|
336
|
+
"""
|
|
337
|
+
|
|
338
|
+
payload = {
|
|
339
|
+
"accountEnabled": account_enabled,
|
|
340
|
+
"displayName": display_name,
|
|
341
|
+
"mailNickname": mail_nickname,
|
|
342
|
+
"userPrincipalName": user_principal_name,
|
|
343
|
+
"passwordProfile": {
|
|
344
|
+
"forceChangePasswordNextSignIn": force_change_password_next_sign_in,
|
|
345
|
+
"password": password,
|
|
346
|
+
},
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
_base_api(
|
|
350
|
+
request="users",
|
|
351
|
+
client="graph",
|
|
352
|
+
status_codes=201,
|
|
353
|
+
payload=payload,
|
|
354
|
+
method="post",
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
print(f"{icons.green_dot} The '{display_name}' user has been created successfully.")
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
@log
|
|
361
|
+
def delete_user(user: str | UUID):
|
|
362
|
+
"""
|
|
363
|
+
Deletes a user.
|
|
364
|
+
|
|
365
|
+
This is a wrapper function for the following API: `Delete User <https://learn.microsoft.com/graph/api/user-delete>`_.
|
|
366
|
+
|
|
367
|
+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
368
|
+
|
|
369
|
+
Parameters
|
|
370
|
+
----------
|
|
371
|
+
user : str | uuid.UUID
|
|
372
|
+
The user name or ID.
|
|
373
|
+
"""
|
|
374
|
+
|
|
375
|
+
user_id = resolve_user_id(user)
|
|
376
|
+
|
|
377
|
+
_base_api(
|
|
378
|
+
request=f"users/{user_id}",
|
|
379
|
+
client="graph",
|
|
380
|
+
status_codes=204,
|
|
381
|
+
method="delete",
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
print(f"{icons.green_dot} The '{user}' user has been deleted successfully.")
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@log
|
|
388
|
+
def update_user(
|
|
389
|
+
user: str | UUID,
|
|
390
|
+
display_name: Optional[str] = None,
|
|
391
|
+
user_principal_name: Optional[str] = None,
|
|
392
|
+
given_name: Optional[str] = None,
|
|
393
|
+
surname: Optional[str] = None,
|
|
394
|
+
job_title: Optional[str] = None,
|
|
395
|
+
mail_nickname: Optional[str] = None,
|
|
396
|
+
my_site: Optional[str] = None,
|
|
397
|
+
office_location: Optional[str] = None,
|
|
398
|
+
account_enabled: Optional[bool] = None,
|
|
399
|
+
):
|
|
400
|
+
"""
|
|
401
|
+
Updates a user's properties.
|
|
402
|
+
|
|
403
|
+
This is a wrapper function for the following API: `Update user <https://learn.microsoft.com/graph/api/user-update>`_.
|
|
404
|
+
|
|
405
|
+
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
|
|
406
|
+
|
|
407
|
+
Parameters
|
|
408
|
+
----------
|
|
409
|
+
user : str | uuid.UUID
|
|
410
|
+
The user name or ID.
|
|
411
|
+
display_name : str, default=None
|
|
412
|
+
The name displayed in the address book for the user.
|
|
413
|
+
user_principal_name : str, default=None
|
|
414
|
+
The user principal name (UPN) of the user.
|
|
415
|
+
given_name : str, default=None
|
|
416
|
+
The given name (first name) of the user.
|
|
417
|
+
surname : str, default=None
|
|
418
|
+
The user's surname (family name or last name).
|
|
419
|
+
job_title : str, default=None
|
|
420
|
+
The user's job title.
|
|
421
|
+
mail_nickname : str, default=None
|
|
422
|
+
The mail alias for the user. This property must be specified when a user is created.
|
|
423
|
+
my_site : str, default=None
|
|
424
|
+
The URL for the user's personal site.
|
|
425
|
+
office_location : str, default=None
|
|
426
|
+
The office location in the user's place of business.
|
|
427
|
+
account_enabled : bool, default=None
|
|
428
|
+
Whether the account is enabled. If None, the property will not be updated.
|
|
429
|
+
"""
|
|
430
|
+
|
|
431
|
+
user_id = resolve_user_id(user)
|
|
432
|
+
|
|
433
|
+
payload = {}
|
|
434
|
+
if display_name is not None:
|
|
435
|
+
payload["displayName"] = display_name
|
|
436
|
+
if mail_nickname is not None:
|
|
437
|
+
payload["mailNickname"] = mail_nickname
|
|
438
|
+
if user_principal_name is not None:
|
|
439
|
+
payload["userPrincipalName"] = user_principal_name
|
|
440
|
+
if given_name is not None:
|
|
441
|
+
payload["givenName"] = given_name
|
|
442
|
+
if job_title is not None:
|
|
443
|
+
payload["jobTitle"] = job_title
|
|
444
|
+
if my_site is not None:
|
|
445
|
+
payload["mySite"] = my_site
|
|
446
|
+
if office_location is not None:
|
|
447
|
+
payload["officeLocation"] = office_location
|
|
448
|
+
if surname is not None:
|
|
449
|
+
payload["surname"] = surname
|
|
450
|
+
if account_enabled is not None and isinstance(account_enabled, bool):
|
|
451
|
+
payload["accountEnabled"] = account_enabled
|
|
452
|
+
|
|
453
|
+
if not payload:
|
|
454
|
+
print(f"{icons.info} No properties to update.")
|
|
455
|
+
return
|
|
456
|
+
|
|
457
|
+
_base_api(
|
|
458
|
+
request=f"users/{user_id}",
|
|
459
|
+
client="graph",
|
|
460
|
+
status_codes=204,
|
|
461
|
+
payload=payload,
|
|
462
|
+
method="patch",
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
print(f"{icons.green_dot} The '{user}' user has been updated successfully.")
|
|
@@ -396,17 +396,22 @@ def list_shortcuts(
|
|
|
396
396
|
# Cache and use it to getitem type and name
|
|
397
397
|
source_item_type = None
|
|
398
398
|
source_item_name = None
|
|
399
|
-
|
|
400
|
-
source_items_df[
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
dfI
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
399
|
+
try:
|
|
400
|
+
dfI = source_items_df[
|
|
401
|
+
source_items_df["Workspace Id"] == source_workspace_id
|
|
402
|
+
]
|
|
403
|
+
if dfI.empty:
|
|
404
|
+
dfI = fabric.list_items(workspace=source_workspace_id)
|
|
405
|
+
source_items_df = pd.concat(
|
|
406
|
+
[source_items_df, dfI], ignore_index=True
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
dfI_filt = dfI[dfI["Id"] == source_item_id]
|
|
410
|
+
if not dfI_filt.empty:
|
|
411
|
+
source_item_type = dfI_filt["Type"].iloc[0]
|
|
412
|
+
source_item_name = dfI_filt["Display Name"].iloc[0]
|
|
413
|
+
except Exception:
|
|
414
|
+
pass
|
|
410
415
|
|
|
411
416
|
rows.append(
|
|
412
417
|
{
|
|
@@ -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
|
+
}
|
|
@@ -935,9 +935,6 @@ class ReportWrapper:
|
|
|
935
935
|
"""
|
|
936
936
|
Shows a list of all modified `visual interactions <https://learn.microsoft.com/power-bi/create-reports/service-reports-visual-interactions?tabs=powerbi-desktop>`_ used in the report.
|
|
937
937
|
|
|
938
|
-
Parameters
|
|
939
|
-
----------
|
|
940
|
-
|
|
941
938
|
Returns
|
|
942
939
|
-------
|
|
943
940
|
pandas.DataFrame
|
|
@@ -980,6 +977,56 @@ class ReportWrapper:
|
|
|
980
977
|
|
|
981
978
|
return df
|
|
982
979
|
|
|
980
|
+
def list_visual_calculations(self) -> pd.DataFrame:
|
|
981
|
+
"""
|
|
982
|
+
Shows a list of all `visual calculations <https://learn.microsoft.com/power-bi/transform-model/desktop-visual-calculations-overview>`_.
|
|
983
|
+
|
|
984
|
+
Returns
|
|
985
|
+
-------
|
|
986
|
+
pandas.DataFrame
|
|
987
|
+
A pandas dataframe containing a list of all visual calculations within the report.
|
|
988
|
+
"""
|
|
989
|
+
|
|
990
|
+
self._ensure_pbir()
|
|
991
|
+
|
|
992
|
+
columns = {
|
|
993
|
+
"Page Display Name": "str",
|
|
994
|
+
"Visual Name": "str",
|
|
995
|
+
"Name": "str",
|
|
996
|
+
"Language": "str",
|
|
997
|
+
"Expression": "str",
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
df = _create_dataframe(columns=columns)
|
|
1001
|
+
visual_mapping = self._visual_page_mapping()
|
|
1002
|
+
|
|
1003
|
+
rows = []
|
|
1004
|
+
for v in self.__all_visuals():
|
|
1005
|
+
path = v.get("path")
|
|
1006
|
+
payload = v.get("payload")
|
|
1007
|
+
page_name = visual_mapping.get(path)[0]
|
|
1008
|
+
page_display_name = visual_mapping.get(path)[1]
|
|
1009
|
+
visual_name = payload.get("name")
|
|
1010
|
+
matches = parse("$..field.NativeVisualCalculation").find(payload)
|
|
1011
|
+
if matches:
|
|
1012
|
+
for match in matches:
|
|
1013
|
+
m = match.value
|
|
1014
|
+
rows.append(
|
|
1015
|
+
{
|
|
1016
|
+
"Page Display Name": page_display_name,
|
|
1017
|
+
"Page Name": page_name,
|
|
1018
|
+
"Visual Name": visual_name,
|
|
1019
|
+
"Name": m.get("Name"),
|
|
1020
|
+
"Language": m.get("Language"),
|
|
1021
|
+
"Expression": m.get("Expression"),
|
|
1022
|
+
}
|
|
1023
|
+
)
|
|
1024
|
+
|
|
1025
|
+
if rows:
|
|
1026
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
1027
|
+
|
|
1028
|
+
return df
|
|
1029
|
+
|
|
983
1030
|
def list_pages(self) -> pd.DataFrame:
|
|
984
1031
|
"""
|
|
985
1032
|
Shows a list of all pages in the report.
|
|
@@ -1651,7 +1698,7 @@ class ReportWrapper:
|
|
|
1651
1698
|
bookmarks = [
|
|
1652
1699
|
o
|
|
1653
1700
|
for o in self._report_definition.get("parts")
|
|
1654
|
-
if o.get("path").endswith("
|
|
1701
|
+
if o.get("path").endswith(".bookmark.json")
|
|
1655
1702
|
]
|
|
1656
1703
|
|
|
1657
1704
|
rows = []
|
|
@@ -2069,8 +2116,8 @@ class ReportWrapper:
|
|
|
2069
2116
|
df = dfCV[dfCV["Used in Report"] == False]
|
|
2070
2117
|
|
|
2071
2118
|
if not df.empty:
|
|
2072
|
-
cv_remove = df["Custom Visual Name"].values
|
|
2073
|
-
cv_remove_display = df["Custom Visual Display Name"].values
|
|
2119
|
+
cv_remove = df["Custom Visual Name"].values
|
|
2120
|
+
cv_remove_display = df["Custom Visual Display Name"].values
|
|
2074
2121
|
else:
|
|
2075
2122
|
print(
|
|
2076
2123
|
f"{icons.red_dot} There are no unnecessary custom visuals in the '{self._report_name}' report within the '{self._workspace_name}' workspace."
|