semantic-link-labs 0.8.8__py3-none-any.whl → 0.8.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of semantic-link-labs might be problematic. Click here for more details.
- {semantic_link_labs-0.8.8.dist-info → semantic_link_labs-0.8.10.dist-info}/METADATA +5 -2
- {semantic_link_labs-0.8.8.dist-info → semantic_link_labs-0.8.10.dist-info}/RECORD +28 -28
- sempy_labs/__init__.py +10 -0
- sempy_labs/_authentication.py +31 -2
- sempy_labs/_dataflows.py +1 -1
- sempy_labs/_dax.py +69 -54
- sempy_labs/_gateways.py +46 -0
- sempy_labs/_generate_semantic_model.py +74 -27
- sempy_labs/_git.py +32 -27
- sempy_labs/_helper_functions.py +60 -23
- sempy_labs/_list_functions.py +178 -32
- sempy_labs/_model_bpa.py +25 -23
- sempy_labs/_model_bpa_bulk.py +5 -5
- sempy_labs/_model_dependencies.py +17 -8
- sempy_labs/_notebooks.py +50 -18
- sempy_labs/_refresh_semantic_model.py +23 -17
- sempy_labs/_translations.py +80 -148
- sempy_labs/_workspaces.py +1 -1
- sempy_labs/admin/__init__.py +6 -0
- sempy_labs/admin/_basic_functions.py +120 -40
- sempy_labs/admin/_domains.py +3 -2
- sempy_labs/admin/_scanner.py +5 -5
- sempy_labs/directlake/_dl_helper.py +13 -8
- sempy_labs/report/_reportwrapper.py +14 -9
- sempy_labs/tom/_model.py +77 -35
- {semantic_link_labs-0.8.8.dist-info → semantic_link_labs-0.8.10.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.8.8.dist-info → semantic_link_labs-0.8.10.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.8.8.dist-info → semantic_link_labs-0.8.10.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: semantic-link-labs
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.10
|
|
4
4
|
Summary: Semantic Link Labs for Microsoft Fabric
|
|
5
5
|
Author: Microsoft Corporation
|
|
6
6
|
License: MIT License
|
|
@@ -27,7 +27,7 @@ Requires-Dist: pytest>=8.2.1; extra == "test"
|
|
|
27
27
|
# Semantic Link Labs
|
|
28
28
|
|
|
29
29
|
[](https://badge.fury.io/py/semantic-link-labs)
|
|
30
|
-
[](https://readthedocs.org/projects/semantic-link-labs/)
|
|
31
31
|
[](https://github.com/psf/black)
|
|
32
32
|
[](https://pepy.tech/project/semantic-link-labs)
|
|
33
33
|
|
|
@@ -64,6 +64,7 @@ Check out the video below for an introduction to Semantic Link, Semantic Link La
|
|
|
64
64
|
* [Dynamically generate a Direct Lake semantic model](https://semantic-link-labs.readthedocs.io/en/stable/sempy_labs.directlake.html#sempy_labs.directlake.generate_direct_lake_semantic_model)
|
|
65
65
|
* [Check why a Direct Lake semantic model would fallback to DirectQuery](https://semantic-link-labs.readthedocs.io/en/stable/sempy_labs.directlake.html#sempy_labs.directlake.check_fallback_reason)
|
|
66
66
|
* [View a measure dependency tree](https://semantic-link-labs.readthedocs.io/en/stable/sempy_labs.html#sempy_labs.measure_dependency_tree)
|
|
67
|
+
* [View unique columns touched in a single (or multiple) DAX query(ies)](https://semantic-link-labs.readthedocs.io/en/stable/sempy_labs.html#sempy_labs.get_dax_query_dependencies)
|
|
67
68
|
* Reports
|
|
68
69
|
* [Report Best Practice Analyzer (BPA)](https://semantic-link-labs.readthedocs.io/en/stable/sempy_labs.report.html#sempy_labs.report.run_report_bpa)
|
|
69
70
|
* [View report metadata](https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Report%20Analysis.ipynb)
|
|
@@ -141,6 +142,8 @@ An even better way to ensure the semantic-link-labs library is available in your
|
|
|
141
142
|
2. Select your newly created environment within the 'Environment' drop down in the navigation bar at the top of the notebook
|
|
142
143
|
|
|
143
144
|
## Version History
|
|
145
|
+
* [0.8.10](https://github.com/microsoft/semantic-link-labs/releases/tag/0.8.10) (December 16, 2024)
|
|
146
|
+
* [0.8.9](https://github.com/microsoft/semantic-link-labs/releases/tag/0.8.9) (December 4, 2024)
|
|
144
147
|
* [0.8.8](https://github.com/microsoft/semantic-link-labs/releases/tag/0.8.8) (November 28, 2024)
|
|
145
148
|
* [0.8.7](https://github.com/microsoft/semantic-link-labs/releases/tag/0.8.7) (November 27, 2024)
|
|
146
149
|
* [0.8.6](https://github.com/microsoft/semantic-link-labs/releases/tag/0.8.6) (November 14, 2024)
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
sempy_labs/__init__.py,sha256=
|
|
1
|
+
sempy_labs/__init__.py,sha256=WyNDrg52pNpAj0s3H7o1vWNYnIpXZrXrKJVYVeC47GQ,13090
|
|
2
2
|
sempy_labs/_ai.py,sha256=CzsNw6Wpd2B5Rd0RcY250-_p0L-0gFoMNLEc_KmrobU,16177
|
|
3
|
-
sempy_labs/_authentication.py,sha256=
|
|
3
|
+
sempy_labs/_authentication.py,sha256=a4sPN8IAf7w-Jftm3PvtF62HqWLkCD69tXgze_G59Zg,4642
|
|
4
4
|
sempy_labs/_capacities.py,sha256=HWX1ivlWpyS7Ea_ny-39kUAQYFGMzo42kWMGdJMINos,25466
|
|
5
5
|
sempy_labs/_capacity_migration.py,sha256=PCIodWXas9v7q93hqD2m8EanJHPJzke52jbCWOfnLZk,27764
|
|
6
6
|
sempy_labs/_clear_cache.py,sha256=ttHsXXR6SRRw4eC0cS8I5h38UbWU9YJii1y-uR9R3KM,12493
|
|
7
7
|
sempy_labs/_connections.py,sha256=-Z3rfLGlUKx5iIGmvwWOICIVZ478ydwvCjxusoJb1RI,17647
|
|
8
8
|
sempy_labs/_data_pipelines.py,sha256=WdZjTELNuN_7suWj6NrZUxGnMTzAgIxFw8V6YMb8ags,5644
|
|
9
|
-
sempy_labs/_dataflows.py,sha256=
|
|
10
|
-
sempy_labs/_dax.py,sha256=
|
|
9
|
+
sempy_labs/_dataflows.py,sha256=D-OuuoUhSrGEhW1mAMBeHULfhULXmmTqIoOdV-se3vs,8250
|
|
10
|
+
sempy_labs/_dax.py,sha256=5lY0p9bS0O2OWViaqTw_9K0WfZsyBW3gK4rIv1bqjjE,9411
|
|
11
11
|
sempy_labs/_deployment_pipelines.py,sha256=WBBQM85-3-MkXb5OmRPF6U83xLyhKSlYUyhRlkvcl4k,6027
|
|
12
12
|
sempy_labs/_documentation.py,sha256=yVA8VPEzx_fmljtcvSxtB7-BeupYsfdMXXjp6Fpnyo8,5007
|
|
13
13
|
sempy_labs/_environments.py,sha256=avpLSfZyyQFdEDIIxWv2THLjPZwbs9XGXT7ob9l_-ao,5326
|
|
14
14
|
sempy_labs/_eventhouses.py,sha256=vgIFQkXcBPC4SnlrBzT7SRmembExxkm6n0gdKnc7Hlk,4036
|
|
15
15
|
sempy_labs/_eventstreams.py,sha256=Rht0eWoZbYF6XKtE3AOUvGgA21smxC9gdN599z-jY3s,4061
|
|
16
16
|
sempy_labs/_external_data_shares.py,sha256=lUsKy1mexNSmhyFwxSeE2jZKNdDAWDP6iC6UPTXCvyU,6799
|
|
17
|
-
sempy_labs/_gateways.py,sha256=
|
|
18
|
-
sempy_labs/_generate_semantic_model.py,sha256=
|
|
19
|
-
sempy_labs/_git.py,sha256=
|
|
20
|
-
sempy_labs/_helper_functions.py,sha256=
|
|
17
|
+
sempy_labs/_gateways.py,sha256=j7REuoG9vGvPcJdII-gOJagprPJctsx3bi-ekUe5q6w,16228
|
|
18
|
+
sempy_labs/_generate_semantic_model.py,sha256=YsPULWDkh2VE-jU3F3jIn0AmZPl3dq03sG-QfuHG2GI,16757
|
|
19
|
+
sempy_labs/_git.py,sha256=gvFR6kCZbegoO_j_hubt-fxuaxRl1KsVldtQNJfnA9U,13870
|
|
20
|
+
sempy_labs/_helper_functions.py,sha256=FtkzTlIJudgGRxrZzjfyon5ehuD8w8KR6sBV74R0XtY,39124
|
|
21
21
|
sempy_labs/_icons.py,sha256=ez2dx_LCti71S_-eB6WYQ-kOMyiBL8ZJN12-ev5dcmA,3579
|
|
22
22
|
sempy_labs/_kql_databases.py,sha256=oNX9oKnXu5SLkzl4kTMQguh4In-i-0Forcoy1phOe1s,4621
|
|
23
23
|
sempy_labs/_kql_querysets.py,sha256=A-79LiLBKxlADPTuSK9ipy_LjXKcsJZwQHknUXFpVl0,4157
|
|
24
|
-
sempy_labs/_list_functions.py,sha256=
|
|
24
|
+
sempy_labs/_list_functions.py,sha256=_5mxBwfTh-BUFWK2lXNPXSpZO0OtP7FlcWaSxwD-Mgs,60939
|
|
25
25
|
sempy_labs/_managed_private_endpoints.py,sha256=bCuC9V4yMFBw1BNlsoxARdIEMPAySW-ljHrhvuziQfw,6179
|
|
26
26
|
sempy_labs/_mirrored_databases.py,sha256=5_5phu50KIvhHNQJ-RQAxd92W4D7GUVMyjAnOb7ZY3Q,14360
|
|
27
27
|
sempy_labs/_mirrored_warehouses.py,sha256=t2fBH5L0UzNahDB4lATDLvmCqYTU-V93_ZVLb5ZISSg,1764
|
|
28
28
|
sempy_labs/_ml_experiments.py,sha256=UVh3cwNvpY-otCBIaKW-sgtzyjwAuu8qJDLhZGBHToE,4196
|
|
29
29
|
sempy_labs/_ml_models.py,sha256=phYLySjN7MO2YYfq7ZQKMS6w18G6L1-7DdNWB4fcLjQ,4044
|
|
30
30
|
sempy_labs/_model_auto_build.py,sha256=PTQo3dufzLSFcQ5shFkmBWAVSdP7cTJgpUclrcXyNbg,5105
|
|
31
|
-
sempy_labs/_model_bpa.py,sha256=
|
|
32
|
-
sempy_labs/_model_bpa_bulk.py,sha256=
|
|
31
|
+
sempy_labs/_model_bpa.py,sha256=nhHAoq9RtOe0lAKRIg9Hr9TBMKxxbGOSCCCs1I8oy1s,21778
|
|
32
|
+
sempy_labs/_model_bpa_bulk.py,sha256=jU-kaeUeE1Slz5HEh3lSbnILzj2tfzMwvaOqOQG16Wg,16027
|
|
33
33
|
sempy_labs/_model_bpa_rules.py,sha256=96_GkXQGhON-_uyUATgUibk4W9y7e9wl1QciUr96gIQ,45544
|
|
34
|
-
sempy_labs/_model_dependencies.py,sha256=
|
|
35
|
-
sempy_labs/_notebooks.py,sha256=
|
|
34
|
+
sempy_labs/_model_dependencies.py,sha256=PL_-ozj3d2L03xR1S-4b-rGhghKbed3QY47x6i5BnfI,12070
|
|
35
|
+
sempy_labs/_notebooks.py,sha256=DTz0byyNMP-JIEn4h85SJ8zMXNrkoChoeV-QE_TvPhE,8280
|
|
36
36
|
sempy_labs/_one_lake_integration.py,sha256=eIuLxlw8eXfUH2avKhsyLmXZbTllSwGsz2j_HMAikpQ,6234
|
|
37
37
|
sempy_labs/_query_scale_out.py,sha256=xoHnuDUgPYsg-NlUplB9ieb0bClcBQeG4veJNo_4TNw,15708
|
|
38
|
-
sempy_labs/_refresh_semantic_model.py,sha256=
|
|
38
|
+
sempy_labs/_refresh_semantic_model.py,sha256=LSfwuViimX6TFq1KlQCMHue7ylzBwaBSrcPzJuvVz2M,17465
|
|
39
39
|
sempy_labs/_spark.py,sha256=RIJt9b_l5Sp5XrebhvRD0DEBKDTQdA8Rh7fByV27ngQ,20109
|
|
40
40
|
sempy_labs/_sql.py,sha256=KttKi95iGxTT8UA1QOpT9ygAdwCfHHlcQSQ5d9gml0E,5358
|
|
41
|
-
sempy_labs/_translations.py,sha256=
|
|
41
|
+
sempy_labs/_translations.py,sha256=CVRd_yJ1pjUzxY_6H8tSCLh67bHhxRyS7DICY20Lqlc,16112
|
|
42
42
|
sempy_labs/_vertipaq.py,sha256=sS9wFPxZfr_5dsOIXd-oeQIeCyXkVeCHbp30Kd7raUU,37662
|
|
43
43
|
sempy_labs/_warehouses.py,sha256=KI7Ww5Slw4jfhby4ensGVlDHLWq6u2SvdMCa2R9i778,7205
|
|
44
44
|
sempy_labs/_workloads.py,sha256=x3dS2mOkrS9rA-p70z8849DZlMIvMbzTjMzO_YmnHRg,4449
|
|
45
45
|
sempy_labs/_workspace_identity.py,sha256=d5cdiiqjyUVoSoDiqU8mzWYOvbt2oJrt7sm-ZGEEkDk,2261
|
|
46
|
-
sempy_labs/_workspaces.py,sha256=
|
|
46
|
+
sempy_labs/_workspaces.py,sha256=Ya_F-2b9LU08xN9bKKRS5LeGs_Ie2o4h26Xgy57IExk,11234
|
|
47
47
|
sempy_labs/_bpa_translation/_model/_translations_am-ET.po,sha256=zQVjJ-t0vtgIYan-HaXtUVJLB_PJvB53Nf5BNoOReU4,39199
|
|
48
48
|
sempy_labs/_bpa_translation/_model/_translations_ar-AE.po,sha256=QP1PjDLFccLDs9zq456crdAST57wrcWVk5rRiqqoCws,36959
|
|
49
49
|
sempy_labs/_bpa_translation/_model/_translations_bg-BG.po,sha256=sqezjpS3wfk09WD7x27bHoCBtgmqeHtyHNKTwG7-bkI,44132
|
|
@@ -82,17 +82,17 @@ sempy_labs/_bpa_translation/_model/_translations_tr-TR.po,sha256=NdW-X4E0QmeLKM0
|
|
|
82
82
|
sempy_labs/_bpa_translation/_model/_translations_uk-UA.po,sha256=3NsFN8hoor_5L6738FjpJ8o4spwp8FNFGbVItHD-_ec,43500
|
|
83
83
|
sempy_labs/_bpa_translation/_model/_translations_zh-CN.po,sha256=ipMbnet7ZI5mZoC8KonYKVwGmFLHFB_9KIDOoBgSNfo,26815
|
|
84
84
|
sempy_labs/_bpa_translation/_model/_translations_zu-ZA.po,sha256=5v6tVKGruqneAeMoa6F3tyg_JBL8qOpqOJofWpq2W3U,31518
|
|
85
|
-
sempy_labs/admin/__init__.py,sha256=
|
|
86
|
-
sempy_labs/admin/_basic_functions.py,sha256=
|
|
87
|
-
sempy_labs/admin/_domains.py,sha256=
|
|
85
|
+
sempy_labs/admin/__init__.py,sha256=YYOwKRfRr6alAez4BImlPcX9bQExATrb856BRq7a3O8,1945
|
|
86
|
+
sempy_labs/admin/_basic_functions.py,sha256=5EEHWDhIFEt94-9yKNecIAMN-KzdBg1uqfdZNoXmnwA,37068
|
|
87
|
+
sempy_labs/admin/_domains.py,sha256=5mv2SzIZCibvHwd4tgm-Lelj0zi66A2KKzQjDQgT9ms,12385
|
|
88
88
|
sempy_labs/admin/_external_data_share.py,sha256=ITsPDgRDfgvZn1cjzpUWyR6lpnoOP0-gJVxjRA3Mp8w,3489
|
|
89
89
|
sempy_labs/admin/_git.py,sha256=OY2F5ICKBXrB1HhlYDWdXQPnhTwSrMfWzEa2xcutClc,2181
|
|
90
90
|
sempy_labs/admin/_items.py,sha256=LqjBYWL3NZCX8f0H-zzjOzy9zlBC7XR4LiknJv_JLT0,8428
|
|
91
|
-
sempy_labs/admin/_scanner.py,sha256=
|
|
91
|
+
sempy_labs/admin/_scanner.py,sha256=OkP2Nc_s-DkYEmfLqiMIf8i3EhVyHfvnT1bPSSnVVss,4476
|
|
92
92
|
sempy_labs/directlake/__init__.py,sha256=etaj-3wqe5t93mu74tGYjEOQ6gtHWUogidOygiVvlq8,2131
|
|
93
93
|
sempy_labs/directlake/_directlake_schema_compare.py,sha256=ocHFU6E6HSKgcNLywGM0dx0ie9AXYwk-E7o7EYcqiN4,4422
|
|
94
94
|
sempy_labs/directlake/_directlake_schema_sync.py,sha256=fhh6Xjd42HjI5x_Ejwq1N4qqnXQsKpXmyPcYl7cNG6A,4151
|
|
95
|
-
sempy_labs/directlake/_dl_helper.py,sha256=
|
|
95
|
+
sempy_labs/directlake/_dl_helper.py,sha256=tG3b0-BJbk-Kwk2B0fyPwoaMgTXS920L61Qz55COex8,9647
|
|
96
96
|
sempy_labs/directlake/_generate_shared_expression.py,sha256=EauK1M4fabCZjsHYAWxEYaVJKqxJ99nZQaN2pKdd1lg,3077
|
|
97
97
|
sempy_labs/directlake/_get_directlake_lakehouse.py,sha256=sovI4ds2SEgkp4Fi465jtJ4seRvQxdYgcixRDvsUwNM,2321
|
|
98
98
|
sempy_labs/directlake/_get_shared_expression.py,sha256=rJ2twFSAMpjdjXl4zkqei_qxzxmGn5DxiDW2KxLcUog,1081
|
|
@@ -126,7 +126,7 @@ sempy_labs/report/_report_functions.py,sha256=nKqsVsjGrv8TUXsBXpb5ejEopAaFELc7Yz
|
|
|
126
126
|
sempy_labs/report/_report_helper.py,sha256=pKIsca-XWaioQd97FgbEfsGPWy4X_NxSyYm22W3C23E,10461
|
|
127
127
|
sempy_labs/report/_report_list_functions.py,sha256=Y0fkoo1gGoVDnihveKruNXFgPJNSiEQ5Fus8bw0nqcU,3381
|
|
128
128
|
sempy_labs/report/_report_rebind.py,sha256=GbOfEb9qz4SdXVGopiWSkGMDKnneJxd7wx4_OWKZ1Js,5188
|
|
129
|
-
sempy_labs/report/_reportwrapper.py,sha256=
|
|
129
|
+
sempy_labs/report/_reportwrapper.py,sha256=ZFcWuZMo9SOzvZ8aPG-DvlZq_MkXRALUJusVIHn7dxE,83049
|
|
130
130
|
sempy_labs/report/_bpareporttemplate/.platform,sha256=kWRa6B_KwSYLsvVFDx372mQriQO8v7dJ_YzQV_cfD-Q,303
|
|
131
131
|
sempy_labs/report/_bpareporttemplate/definition.pbir,sha256=bttyHZYKqjA8OBb_cezGlX4H82cDvGZVCl1QB3fij4E,343
|
|
132
132
|
sempy_labs/report/_bpareporttemplate/.pbi/localSettings.json,sha256=kzjBlNdjbsSBBSHBwbQc298AJCr9Vp6Ex0D5PemUuT0,1578
|
|
@@ -157,9 +157,9 @@ sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visua
|
|
|
157
157
|
sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/page.json,sha256=wBVuNc8S2NaUA0FC708w6stmR2djNZp8nAsHMqesgsc,293
|
|
158
158
|
sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/visuals/ce8532a7e25020271077/visual.json,sha256=mlY6t9OlSe-Y6_QmXJpS1vggU6Y3FjISUKECL8FVSg8,931
|
|
159
159
|
sempy_labs/tom/__init__.py,sha256=Qbs8leW0fjzvWwOjyWK3Hjeehu7IvpB1beASGsi28bk,121
|
|
160
|
-
sempy_labs/tom/_model.py,sha256=
|
|
161
|
-
semantic_link_labs-0.8.
|
|
162
|
-
semantic_link_labs-0.8.
|
|
163
|
-
semantic_link_labs-0.8.
|
|
164
|
-
semantic_link_labs-0.8.
|
|
165
|
-
semantic_link_labs-0.8.
|
|
160
|
+
sempy_labs/tom/_model.py,sha256=rBMI9BTSuTEH1MnJsUIVtsc45x7EOQ2fAxcYkwYgfZw,173575
|
|
161
|
+
semantic_link_labs-0.8.10.dist-info/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
|
|
162
|
+
semantic_link_labs-0.8.10.dist-info/METADATA,sha256=eITmLRcqLr0Yuitj1Q1LXmWYDH5AA-fbpwWUDGWQuO4,21196
|
|
163
|
+
semantic_link_labs-0.8.10.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
164
|
+
semantic_link_labs-0.8.10.dist-info/top_level.txt,sha256=kiQX1y42Dbein1l3Q8jMUYyRulDjdlc2tMepvtrvixQ,11
|
|
165
|
+
semantic_link_labs-0.8.10.dist-info/RECORD,,
|
sempy_labs/__init__.py
CHANGED
|
@@ -8,6 +8,7 @@ from sempy_labs._gateways import (
|
|
|
8
8
|
create_vnet_gateway,
|
|
9
9
|
update_vnet_gateway,
|
|
10
10
|
update_on_premises_gateway,
|
|
11
|
+
bind_semantic_model_to_gateway,
|
|
11
12
|
)
|
|
12
13
|
|
|
13
14
|
from sempy_labs._authentication import (
|
|
@@ -190,6 +191,7 @@ from sempy_labs._generate_semantic_model import (
|
|
|
190
191
|
get_semantic_model_bim,
|
|
191
192
|
get_semantic_model_size,
|
|
192
193
|
update_semantic_model_from_bim,
|
|
194
|
+
get_semantic_model_definition,
|
|
193
195
|
)
|
|
194
196
|
from sempy_labs._list_functions import (
|
|
195
197
|
list_reports_using_semantic_model,
|
|
@@ -204,6 +206,8 @@ from sempy_labs._list_functions import (
|
|
|
204
206
|
list_lakehouses,
|
|
205
207
|
list_sql_endpoints,
|
|
206
208
|
update_item,
|
|
209
|
+
list_server_properties,
|
|
210
|
+
list_semantic_model_errors,
|
|
207
211
|
)
|
|
208
212
|
from sempy_labs._helper_functions import (
|
|
209
213
|
convert_to_friendly_case,
|
|
@@ -229,6 +233,7 @@ from sempy_labs._helper_functions import (
|
|
|
229
233
|
get_capacity_id,
|
|
230
234
|
get_capacity_name,
|
|
231
235
|
resolve_capacity_name,
|
|
236
|
+
get_tenant_id,
|
|
232
237
|
)
|
|
233
238
|
from sempy_labs._model_bpa_bulk import (
|
|
234
239
|
run_model_bpa_bulk,
|
|
@@ -456,4 +461,9 @@ __all__ = [
|
|
|
456
461
|
"create_vnet_gateway",
|
|
457
462
|
"update_vnet_gateway",
|
|
458
463
|
"update_on_premises_gateway",
|
|
464
|
+
"get_semantic_model_definition",
|
|
465
|
+
"get_tenant_id",
|
|
466
|
+
"list_server_properties",
|
|
467
|
+
"bind_semantic_model_to_gateway",
|
|
468
|
+
"list_semantic_model_errors",
|
|
459
469
|
]
|
sempy_labs/_authentication.py
CHANGED
|
@@ -91,11 +91,13 @@ class ServicePrincipalTokenProvider(TokenProvider):
|
|
|
91
91
|
|
|
92
92
|
return cls(credential)
|
|
93
93
|
|
|
94
|
-
def __call__(
|
|
94
|
+
def __call__(
|
|
95
|
+
self, audience: Literal["pbi", "storage", "azure", "graph"] = "pbi"
|
|
96
|
+
) -> str:
|
|
95
97
|
"""
|
|
96
98
|
Parameters
|
|
97
99
|
----------
|
|
98
|
-
audience : Literal["pbi", "storage"] = "pbi") -> str
|
|
100
|
+
audience : Literal["pbi", "storage", "azure", "graph"] = "pbi") -> str
|
|
99
101
|
Literal if it's for PBI/Fabric API call or OneLake/Storage Account call.
|
|
100
102
|
"""
|
|
101
103
|
if audience == "pbi":
|
|
@@ -104,5 +106,32 @@ class ServicePrincipalTokenProvider(TokenProvider):
|
|
|
104
106
|
).token
|
|
105
107
|
elif audience == "storage":
|
|
106
108
|
return self.credential.get_token("https://storage.azure.com/.default").token
|
|
109
|
+
elif audience == "azure":
|
|
110
|
+
return self.credential.get_token(
|
|
111
|
+
"https://management.azure.com/.default"
|
|
112
|
+
).token
|
|
113
|
+
elif audience == "graph":
|
|
114
|
+
return self.credential.get_token(
|
|
115
|
+
"https://graph.microsoft.com/.default"
|
|
116
|
+
).token
|
|
107
117
|
else:
|
|
108
118
|
raise NotImplementedError
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _get_headers(
|
|
122
|
+
token_provider: str, audience: Literal["pbi", "storage", "azure", "graph"] = "azure"
|
|
123
|
+
):
|
|
124
|
+
"""
|
|
125
|
+
Generates headers for an API request.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
token = token_provider(audience=audience)
|
|
129
|
+
|
|
130
|
+
headers = {"Authorization": f"Bearer {token}"}
|
|
131
|
+
|
|
132
|
+
if audience == "graph":
|
|
133
|
+
headers["ConsistencyLevel"] = "eventual"
|
|
134
|
+
else:
|
|
135
|
+
headers["Content-Type"] = "application/json"
|
|
136
|
+
|
|
137
|
+
return headers
|
sempy_labs/_dataflows.py
CHANGED
|
@@ -42,7 +42,7 @@ def list_dataflows(workspace: Optional[str] = None):
|
|
|
42
42
|
"Dataflow Id": v.get("objectId"),
|
|
43
43
|
"Dataflow Name": v.get("name"),
|
|
44
44
|
"Configured By": v.get("configuredBy"),
|
|
45
|
-
"Users":
|
|
45
|
+
"Users": v.get("users"),
|
|
46
46
|
"Generation": v.get("generation"),
|
|
47
47
|
}
|
|
48
48
|
df = pd.concat(
|
sempy_labs/_dax.py
CHANGED
|
@@ -6,7 +6,7 @@ from sempy_labs._helper_functions import (
|
|
|
6
6
|
format_dax_object_name,
|
|
7
7
|
)
|
|
8
8
|
from sempy_labs._model_dependencies import get_model_calc_dependencies
|
|
9
|
-
from typing import Optional
|
|
9
|
+
from typing import Optional, List
|
|
10
10
|
from sempy._utils._log import log
|
|
11
11
|
from tqdm.auto import tqdm
|
|
12
12
|
|
|
@@ -67,8 +67,9 @@ def evaluate_dax_impersonation(
|
|
|
67
67
|
@log
|
|
68
68
|
def get_dax_query_dependencies(
|
|
69
69
|
dataset: str,
|
|
70
|
-
dax_string: str,
|
|
70
|
+
dax_string: str | List[str],
|
|
71
71
|
put_in_memory: bool = False,
|
|
72
|
+
show_vertipaq_stats: bool = True,
|
|
72
73
|
workspace: Optional[str] = None,
|
|
73
74
|
) -> pd.DataFrame:
|
|
74
75
|
"""
|
|
@@ -78,10 +79,12 @@ def get_dax_query_dependencies(
|
|
|
78
79
|
----------
|
|
79
80
|
dataset : str
|
|
80
81
|
Name of the semantic model.
|
|
81
|
-
dax_string : str
|
|
82
|
-
The DAX query.
|
|
82
|
+
dax_string : str | List[str]
|
|
83
|
+
The DAX query or list of DAX queries.
|
|
83
84
|
put_in_memory : bool, default=False
|
|
84
85
|
If True, ensures that the dependent columns are put into memory in order to give realistic Vertipaq stats (i.e. Total Size etc.).
|
|
86
|
+
show_vertipaq_stats : bool, default=True
|
|
87
|
+
If True, shows vertipaq stats (i.e. Total Size, Data Size, Dictionary Size, Hierarchy Size)
|
|
85
88
|
workspace : str, default=None
|
|
86
89
|
The Fabric workspace name.
|
|
87
90
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
@@ -96,67 +99,79 @@ def get_dax_query_dependencies(
|
|
|
96
99
|
if workspace is None:
|
|
97
100
|
workspace = fabric.resolve_workspace_name(workspace)
|
|
98
101
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
final_query = f"""
|
|
102
|
-
EVALUATE
|
|
103
|
-
VAR source_query = "{dax_string}"
|
|
104
|
-
VAR all_dependencies = SELECTCOLUMNS(
|
|
105
|
-
INFO.CALCDEPENDENCY("QUERY", source_query),
|
|
106
|
-
"Referenced Object Type",[REFERENCED_OBJECT_TYPE],
|
|
107
|
-
"Referenced Table", [REFERENCED_TABLE],
|
|
108
|
-
"Referenced Object", [REFERENCED_OBJECT]
|
|
109
|
-
)
|
|
110
|
-
RETURN all_dependencies
|
|
111
|
-
"""
|
|
112
|
-
dep = fabric.evaluate_dax(
|
|
113
|
-
dataset=dataset, workspace=workspace, dax_string=final_query
|
|
114
|
-
)
|
|
102
|
+
if isinstance(dax_string, str):
|
|
103
|
+
dax_string = [dax_string]
|
|
115
104
|
|
|
116
|
-
|
|
117
|
-
dep.columns = dep.columns.map(lambda x: x[1:-1])
|
|
118
|
-
dep["Referenced Object Type"] = (
|
|
119
|
-
dep["Referenced Object Type"].str.replace("_", " ").str.title()
|
|
120
|
-
)
|
|
121
|
-
dep
|
|
122
|
-
|
|
123
|
-
# Dataframe df will contain the output of all dependencies of the objects used in the query
|
|
124
|
-
df = dep.copy()
|
|
105
|
+
final_df = pd.DataFrame(columns=["Object Type", "Table", "Object"])
|
|
125
106
|
|
|
126
107
|
cd = get_model_calc_dependencies(dataset=dataset, workspace=workspace)
|
|
127
108
|
|
|
128
|
-
for
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
109
|
+
for dax in dax_string:
|
|
110
|
+
# Escape quotes in dax
|
|
111
|
+
dax = dax.replace('"', '""')
|
|
112
|
+
final_query = f"""
|
|
113
|
+
EVALUATE
|
|
114
|
+
VAR source_query = "{dax}"
|
|
115
|
+
VAR all_dependencies = SELECTCOLUMNS(
|
|
116
|
+
INFO.CALCDEPENDENCY("QUERY", source_query),
|
|
117
|
+
"Referenced Object Type",[REFERENCED_OBJECT_TYPE],
|
|
118
|
+
"Referenced Table", [REFERENCED_TABLE],
|
|
119
|
+
"Referenced Object", [REFERENCED_OBJECT]
|
|
120
|
+
)
|
|
121
|
+
RETURN all_dependencies
|
|
122
|
+
"""
|
|
123
|
+
dep = fabric.evaluate_dax(
|
|
124
|
+
dataset=dataset, workspace=workspace, dax_string=final_query
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# Clean up column names and values (remove outside square brackets, underscorees in object type)
|
|
128
|
+
dep.columns = dep.columns.map(lambda x: x[1:-1])
|
|
129
|
+
dep["Referenced Object Type"] = (
|
|
130
|
+
dep["Referenced Object Type"].str.replace("_", " ").str.title()
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# Dataframe df will contain the output of all dependencies of the objects used in the query
|
|
134
|
+
df = dep.copy()
|
|
135
|
+
|
|
136
|
+
for _, r in dep.iterrows():
|
|
137
|
+
ot = r["Referenced Object Type"]
|
|
138
|
+
object_name = r["Referenced Object"]
|
|
139
|
+
table_name = r["Referenced Table"]
|
|
140
|
+
cd_filt = cd[
|
|
141
|
+
(cd["Object Type"] == ot)
|
|
142
|
+
& (cd["Object Name"] == object_name)
|
|
143
|
+
& (cd["Table Name"] == table_name)
|
|
142
144
|
]
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
|
|
146
|
+
# Adds in the dependencies of each object used in the query (i.e. relationship etc.)
|
|
147
|
+
if len(cd_filt) > 0:
|
|
148
|
+
subset = cd_filt[
|
|
149
|
+
["Referenced Object Type", "Referenced Table", "Referenced Object"]
|
|
150
|
+
]
|
|
151
|
+
df = pd.concat([df, subset], ignore_index=True)
|
|
152
|
+
|
|
153
|
+
df.columns = df.columns.map(lambda x: x.replace("Referenced ", ""))
|
|
154
|
+
final_df = pd.concat([df, final_df], ignore_index=True)
|
|
155
|
+
|
|
156
|
+
final_df = final_df[
|
|
157
|
+
(final_df["Object Type"].isin(["Column", "Calc Column"]))
|
|
158
|
+
& (~final_df["Object"].str.startswith("RowNumber-"))
|
|
152
159
|
]
|
|
160
|
+
final_df = final_df.drop_duplicates().reset_index(drop=True)
|
|
161
|
+
final_df = final_df.rename(columns={"Table": "Table Name", "Object": "Column Name"})
|
|
162
|
+
final_df.drop(columns=["Object Type"], inplace=True)
|
|
163
|
+
|
|
164
|
+
if not show_vertipaq_stats:
|
|
165
|
+
return final_df
|
|
153
166
|
|
|
154
167
|
# Get vertipaq stats, filter to just the objects in the df dataframe
|
|
155
|
-
|
|
168
|
+
final_df["Full Object"] = format_dax_object_name(
|
|
169
|
+
final_df["Table Name"], final_df["Column Name"]
|
|
170
|
+
)
|
|
156
171
|
dfC = fabric.list_columns(dataset=dataset, workspace=workspace, extended=True)
|
|
157
172
|
dfC["Full Object"] = format_dax_object_name(dfC["Table Name"], dfC["Column Name"])
|
|
158
173
|
|
|
159
|
-
dfC_filtered = dfC[dfC["Full Object"].isin(
|
|
174
|
+
dfC_filtered = dfC[dfC["Full Object"].isin(final_df["Full Object"].values)][
|
|
160
175
|
[
|
|
161
176
|
"Table Name",
|
|
162
177
|
"Column Name",
|
sempy_labs/_gateways.py
CHANGED
|
@@ -6,6 +6,8 @@ from sempy_labs._helper_functions import (
|
|
|
6
6
|
pagination,
|
|
7
7
|
_is_valid_uuid,
|
|
8
8
|
resolve_capacity_id,
|
|
9
|
+
resolve_workspace_name_and_id,
|
|
10
|
+
resolve_dataset_name_and_id,
|
|
9
11
|
)
|
|
10
12
|
from uuid import UUID
|
|
11
13
|
import sempy_labs._icons as icons
|
|
@@ -437,3 +439,47 @@ def update_vnet_gateway(
|
|
|
437
439
|
raise FabricHTTPException(response)
|
|
438
440
|
|
|
439
441
|
print(f"{icons.green_dot} The '{gateway}' has been updated accordingly.")
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
def bind_semantic_model_to_gateway(
|
|
445
|
+
dataset: str | UUID, gateway: str | UUID, workspace: Optional[str | UUID] = None
|
|
446
|
+
):
|
|
447
|
+
"""
|
|
448
|
+
Binds the specified dataset from the specified workspace to the specified gateway.
|
|
449
|
+
|
|
450
|
+
This is a wrapper function for the following API: `Datasets - Bind To Gateway In Group <https://learn.microsoft.com/rest/api/power-bi/datasets/bind-to-gateway-in-group>`_.
|
|
451
|
+
|
|
452
|
+
Parameters
|
|
453
|
+
----------
|
|
454
|
+
dataset : str | UUID
|
|
455
|
+
The name or ID of the semantic model.
|
|
456
|
+
gateway : str | UUID
|
|
457
|
+
The name or ID of the gateway.
|
|
458
|
+
workspace : str | UUID, default=None
|
|
459
|
+
The Fabric workspace name.
|
|
460
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
461
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
462
|
+
"""
|
|
463
|
+
|
|
464
|
+
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
465
|
+
(dataset_name, dataset_id) = resolve_dataset_name_and_id(
|
|
466
|
+
dataset, workspace=workspace_id
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
gateway_id = _resolve_gateway_id(gateway)
|
|
470
|
+
payload = {
|
|
471
|
+
"gatewayObjectId": gateway_id,
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
client = fabric.FabricRestClient()
|
|
475
|
+
response = client.post(
|
|
476
|
+
f"/v1.0/myorg/groups/{workspace_id}/datasets/{dataset_id}/Default.BindToGateway",
|
|
477
|
+
json=payload,
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
if response.status_code != 200:
|
|
481
|
+
raise FabricHTTPException(response)
|
|
482
|
+
|
|
483
|
+
print(
|
|
484
|
+
f"{icons.green_dot} The '{dataset_name}' semantic model within the '{workspace_name}' workspace has been binded to the '{gateway_id}' gateway."
|
|
485
|
+
)
|
|
@@ -2,7 +2,7 @@ import sempy.fabric as fabric
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
-
from typing import Optional
|
|
5
|
+
from typing import Optional, List
|
|
6
6
|
from sempy_labs._helper_functions import (
|
|
7
7
|
resolve_lakehouse_name,
|
|
8
8
|
resolve_workspace_name_and_id,
|
|
@@ -203,14 +203,7 @@ def update_semantic_model_from_bim(
|
|
|
203
203
|
"""
|
|
204
204
|
|
|
205
205
|
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
206
|
-
|
|
207
|
-
dfD = fabric.list_datasets(workspace=workspace, mode="rest")
|
|
208
|
-
dfD_filt = dfD[dfD["Dataset Name"] == dataset]
|
|
209
|
-
if len(dfD_filt) == 0:
|
|
210
|
-
raise ValueError(
|
|
211
|
-
f"{icons.red_dot} The '{dataset}' semantic model within the '{workspace}' workspace does not exist."
|
|
212
|
-
)
|
|
213
|
-
dataset_id = dfD_filt["Dataset Id"].iloc[0]
|
|
206
|
+
dataset_id = resolve_dataset_id(dataset=dataset, workspace=workspace)
|
|
214
207
|
|
|
215
208
|
client = fabric.FabricRestClient()
|
|
216
209
|
defPBIDataset = {"version": "1.0", "settings": {}}
|
|
@@ -303,12 +296,11 @@ def deploy_semantic_model(
|
|
|
303
296
|
bim = get_semantic_model_bim(dataset=source_dataset, workspace=source_workspace)
|
|
304
297
|
|
|
305
298
|
# Create the semantic model if the model does not exist
|
|
306
|
-
if
|
|
299
|
+
if dfD_filt.empty:
|
|
307
300
|
create_semantic_model_from_bim(
|
|
308
301
|
dataset=target_dataset,
|
|
309
302
|
bim_file=bim,
|
|
310
303
|
workspace=target_workspace,
|
|
311
|
-
overwrite=overwrite,
|
|
312
304
|
)
|
|
313
305
|
# Update the semantic model if the model exists
|
|
314
306
|
else:
|
|
@@ -329,8 +321,6 @@ def get_semantic_model_bim(
|
|
|
329
321
|
"""
|
|
330
322
|
Extracts the Model.bim file for a given semantic model.
|
|
331
323
|
|
|
332
|
-
This is a wrapper function for the following API: `Items - Get Semantic Model Definition <https://learn.microsoft.com/rest/api/fabric/semanticmodel/items/get-semantic-model-definition>`_.
|
|
333
|
-
|
|
334
324
|
Parameters
|
|
335
325
|
----------
|
|
336
326
|
dataset : str
|
|
@@ -352,20 +342,9 @@ def get_semantic_model_bim(
|
|
|
352
342
|
The Model.bim file for the semantic model.
|
|
353
343
|
"""
|
|
354
344
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
fmt = "TMSL"
|
|
358
|
-
client = fabric.FabricRestClient()
|
|
359
|
-
dataset_id = resolve_dataset_id(dataset=dataset, workspace=workspace)
|
|
360
|
-
response = client.post(
|
|
361
|
-
f"/v1/workspaces/{workspace_id}/semanticModels/{dataset_id}/getDefinition?format={fmt}",
|
|
345
|
+
bimJson = get_semantic_model_definition(
|
|
346
|
+
dataset=dataset, workspace=workspace, format="TMSL", return_dataframe=False
|
|
362
347
|
)
|
|
363
|
-
result = lro(client, response).json()
|
|
364
|
-
df_items = pd.json_normalize(result["definition"]["parts"])
|
|
365
|
-
df_items_filt = df_items[df_items["path"] == "model.bim"]
|
|
366
|
-
payload = df_items_filt["payload"].iloc[0]
|
|
367
|
-
bimFile = _decode_b64(payload)
|
|
368
|
-
bimJson = json.loads(bimFile)
|
|
369
348
|
|
|
370
349
|
if save_to_file_name is not None:
|
|
371
350
|
if not lakehouse_attached():
|
|
@@ -384,12 +363,80 @@ def get_semantic_model_bim(
|
|
|
384
363
|
with open(filePath, "w") as json_file:
|
|
385
364
|
json.dump(bimJson, json_file, indent=4)
|
|
386
365
|
print(
|
|
387
|
-
f"{icons.green_dot} The
|
|
366
|
+
f"{icons.green_dot} The {fileExt} file for the '{dataset}' semantic model has been saved to the '{lakehouse}' in this location: '{filePath}'.\n\n"
|
|
388
367
|
)
|
|
389
368
|
|
|
390
369
|
return bimJson
|
|
391
370
|
|
|
392
371
|
|
|
372
|
+
def get_semantic_model_definition(
|
|
373
|
+
dataset: str,
|
|
374
|
+
format: str = "TMSL",
|
|
375
|
+
workspace: Optional[str] = None,
|
|
376
|
+
return_dataframe: bool = True,
|
|
377
|
+
) -> pd.DataFrame | dict | List:
|
|
378
|
+
"""
|
|
379
|
+
Extracts the semantic model definition.
|
|
380
|
+
|
|
381
|
+
This is a wrapper function for the following API: `Items - Get Semantic Model Definition <https://learn.microsoft.com/rest/api/fabric/semanticmodel/items/get-semantic-model-definition>`_.
|
|
382
|
+
|
|
383
|
+
Parameters
|
|
384
|
+
----------
|
|
385
|
+
dataset : str
|
|
386
|
+
Name of the semantic model.
|
|
387
|
+
format : str, default="TMSL"
|
|
388
|
+
The output format. Valid options are "TMSL" or "TMDL". "TMSL" returns the .bim file whereas "TMDL" returns the collection of TMDL files. Can also enter 'bim' for the TMSL version.
|
|
389
|
+
workspace : str, default=None
|
|
390
|
+
The Fabric workspace name in which the semantic model resides.
|
|
391
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
392
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
393
|
+
return_dataframe : bool, default=True
|
|
394
|
+
If True, returns a dataframe.
|
|
395
|
+
If False, returns the .bim file for TMSL format. Returns a list of the TMDL files (decoded) for TMDL format.
|
|
396
|
+
|
|
397
|
+
Returns
|
|
398
|
+
-------
|
|
399
|
+
pandas.DataFrame | dict | List
|
|
400
|
+
A pandas dataframe with the semantic model definition or the file or files comprising the semantic model definition.
|
|
401
|
+
"""
|
|
402
|
+
|
|
403
|
+
valid_formats = ["TMSL", "TMDL"]
|
|
404
|
+
|
|
405
|
+
format = format.upper()
|
|
406
|
+
if format == "BIM":
|
|
407
|
+
format = "TMSL"
|
|
408
|
+
if format not in valid_formats:
|
|
409
|
+
raise ValueError(
|
|
410
|
+
f"{icons.red_dot} Invalid format. Valid options: {valid_formats}."
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
(workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
414
|
+
|
|
415
|
+
client = fabric.FabricRestClient()
|
|
416
|
+
dataset_id = resolve_dataset_id(dataset=dataset, workspace=workspace)
|
|
417
|
+
response = client.post(
|
|
418
|
+
f"/v1/workspaces/{workspace_id}/semanticModels/{dataset_id}/getDefinition?format={format}",
|
|
419
|
+
)
|
|
420
|
+
result = lro(client, response).json()
|
|
421
|
+
|
|
422
|
+
files = result["definition"]["parts"]
|
|
423
|
+
|
|
424
|
+
if return_dataframe:
|
|
425
|
+
return pd.json_normalize(files)
|
|
426
|
+
elif format == "TMSL":
|
|
427
|
+
payload = next(
|
|
428
|
+
(part["payload"] for part in files if part["path"] == "model.bim"), None
|
|
429
|
+
)
|
|
430
|
+
return json.loads(_decode_b64(payload))
|
|
431
|
+
else:
|
|
432
|
+
decoded_parts = [
|
|
433
|
+
{"file_name": part["path"], "content": _decode_b64(part["payload"])}
|
|
434
|
+
for part in files
|
|
435
|
+
]
|
|
436
|
+
|
|
437
|
+
return decoded_parts
|
|
438
|
+
|
|
439
|
+
|
|
393
440
|
def get_semantic_model_size(dataset: str, workspace: Optional[str] = None):
|
|
394
441
|
|
|
395
442
|
workspace = fabric.resolve_workspace_name(workspace)
|