semantic-link-labs 0.4.2__py3-none-any.whl → 0.5.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.4.2.dist-info → semantic_link_labs-0.5.0.dist-info}/METADATA +1 -1
- semantic_link_labs-0.5.0.dist-info/RECORD +53 -0
- {semantic_link_labs-0.4.2.dist-info → semantic_link_labs-0.5.0.dist-info}/WHEEL +1 -1
- sempy_labs/__init__.py +27 -3
- sempy_labs/_ai.py +12 -32
- sempy_labs/_clear_cache.py +1 -3
- sempy_labs/_connections.py +39 -38
- sempy_labs/_generate_semantic_model.py +9 -14
- sempy_labs/_helper_functions.py +3 -12
- sempy_labs/_icons.py +1 -0
- sempy_labs/_list_functions.py +915 -391
- sempy_labs/_model_auto_build.py +2 -4
- sempy_labs/_model_bpa.py +26 -30
- sempy_labs/_model_dependencies.py +7 -13
- sempy_labs/_one_lake_integration.py +2 -5
- sempy_labs/_query_scale_out.py +12 -30
- sempy_labs/_refresh_semantic_model.py +5 -15
- sempy_labs/_translations.py +1 -1
- sempy_labs/_vertipaq.py +3 -10
- sempy_labs/directlake/_directlake_schema_compare.py +3 -9
- sempy_labs/directlake/_directlake_schema_sync.py +2 -6
- sempy_labs/directlake/_fallback.py +2 -6
- sempy_labs/directlake/_get_shared_expression.py +3 -9
- sempy_labs/directlake/_guardrails.py +3 -5
- sempy_labs/directlake/_list_directlake_model_calc_tables.py +3 -4
- sempy_labs/directlake/_show_unsupported_directlake_objects.py +1 -2
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +3 -7
- sempy_labs/directlake/_update_directlake_partition_entity.py +2 -8
- sempy_labs/directlake/_warm_cache.py +5 -8
- sempy_labs/lakehouse/_get_lakehouse_columns.py +1 -1
- sempy_labs/lakehouse/_get_lakehouse_tables.py +3 -5
- sempy_labs/lakehouse/_lakehouse.py +1 -3
- sempy_labs/lakehouse/_shortcuts.py +2 -5
- sempy_labs/migration/_create_pqt_file.py +4 -13
- sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +2 -6
- sempy_labs/migration/_migration_validation.py +4 -0
- sempy_labs/migration/_refresh_calc_tables.py +2 -0
- sempy_labs/report/_generate_report.py +2 -6
- sempy_labs/report/_report_functions.py +30 -73
- sempy_labs/report/_report_rebind.py +39 -39
- sempy_labs/tom/_model.py +141 -183
- semantic_link_labs-0.4.2.dist-info/RECORD +0 -53
- {semantic_link_labs-0.4.2.dist-info → semantic_link_labs-0.5.0.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.4.2.dist-info → semantic_link_labs-0.5.0.dist-info}/top_level.txt +0 -0
sempy_labs/tom/_model.py
CHANGED
|
@@ -93,7 +93,7 @@ class TOMWrapper:
|
|
|
93
93
|
import Microsoft.AnalysisServices.Tabular as TOM
|
|
94
94
|
|
|
95
95
|
for t in self.model.Tables:
|
|
96
|
-
if any(p.SourceType == TOM.
|
|
96
|
+
if any(p.SourceType == TOM.PartitionSourceType.Calculated for p in t.Partitions):
|
|
97
97
|
yield t
|
|
98
98
|
|
|
99
99
|
def all_calculation_groups(self):
|
|
@@ -658,22 +658,16 @@ class TOMWrapper:
|
|
|
658
658
|
import Microsoft.AnalysisServices.Tabular as TOM
|
|
659
659
|
|
|
660
660
|
if isinstance(columns, str):
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
)
|
|
664
|
-
return
|
|
661
|
+
raise ValueError(f"{icons.red_dot} The 'levels' parameter must be a list. For example: ['Continent', 'Country', 'City']")
|
|
662
|
+
|
|
665
663
|
if len(columns) == 1:
|
|
666
|
-
|
|
667
|
-
return
|
|
664
|
+
raise ValueError(f"{icons.red_dot} There must be at least 2 levels in order to create a hierarchy.")
|
|
668
665
|
|
|
669
666
|
if levels is None:
|
|
670
667
|
levels = columns
|
|
671
668
|
|
|
672
669
|
if len(columns) != len(levels):
|
|
673
|
-
|
|
674
|
-
f"{icons.red_dot} If specifying level names, you must specify a level for each column."
|
|
675
|
-
)
|
|
676
|
-
return
|
|
670
|
+
raise ValueError(f"{icons.red_dot} If specifying level names, you must specify a level for each column.")
|
|
677
671
|
|
|
678
672
|
obj = TOM.Hierarchy()
|
|
679
673
|
obj.Name = hierarchy_name
|
|
@@ -1003,9 +997,7 @@ class TOMWrapper:
|
|
|
1003
997
|
import System
|
|
1004
998
|
|
|
1005
999
|
if base_column is not None and base_table is None:
|
|
1006
|
-
|
|
1007
|
-
f"{icons.red_dot} If you specify the base table you must also specify the base column"
|
|
1008
|
-
)
|
|
1000
|
+
raise ValueError(f"{icons.red_dot} If you specify the base table you must also specify the base column")
|
|
1009
1001
|
|
|
1010
1002
|
summarization_type = (
|
|
1011
1003
|
summarization_type.replace(" ", "")
|
|
@@ -1015,10 +1007,7 @@ class TOMWrapper:
|
|
|
1015
1007
|
|
|
1016
1008
|
summarizationTypes = ["Sum", "GroupBy", "Count", "Min", "Max"]
|
|
1017
1009
|
if summarization_type not in summarizationTypes:
|
|
1018
|
-
|
|
1019
|
-
f"{icons.red_dot} The 'summarization_type' parameter must be one of the following valuse: {summarizationTypes}."
|
|
1020
|
-
)
|
|
1021
|
-
return
|
|
1010
|
+
raise ValueError(f"{icons.red_dot} The 'summarization_type' parameter must be one of the following valuse: {summarizationTypes}.")
|
|
1022
1011
|
|
|
1023
1012
|
ao = TOM.AlternateOf()
|
|
1024
1013
|
ao.Summarization = System.Enum.Parse(TOM.SummarizationType, summarization_type)
|
|
@@ -1277,10 +1266,7 @@ class TOMWrapper:
|
|
|
1277
1266
|
objectType = object.ObjectType
|
|
1278
1267
|
|
|
1279
1268
|
if objectType not in validObjects:
|
|
1280
|
-
|
|
1281
|
-
f"{icons.red_dot} Only the following object types are valid for perspectives: {validObjects}."
|
|
1282
|
-
)
|
|
1283
|
-
return
|
|
1269
|
+
raise ValueError(f"{icons.red_dot} Only the following object types are valid for perspectives: {validObjects}.")
|
|
1284
1270
|
|
|
1285
1271
|
object.Model.Perspectives[perspective_name]
|
|
1286
1272
|
|
|
@@ -1331,15 +1317,12 @@ class TOMWrapper:
|
|
|
1331
1317
|
objectType = object.ObjectType
|
|
1332
1318
|
|
|
1333
1319
|
if objectType not in validObjects:
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
)
|
|
1337
|
-
return
|
|
1320
|
+
raise ValueError(f"{icons.red_dot} Only the following object types are valid for perspectives: {validObjects}.")
|
|
1321
|
+
|
|
1338
1322
|
try:
|
|
1339
1323
|
object.Model.Perspectives[perspective_name]
|
|
1340
1324
|
except:
|
|
1341
|
-
|
|
1342
|
-
return
|
|
1325
|
+
raise ValueError(f"{icons.red_dot} The '{perspective_name}' perspective does not exist.")
|
|
1343
1326
|
|
|
1344
1327
|
# try:
|
|
1345
1328
|
if objectType == TOM.ObjectType.Table:
|
|
@@ -1393,15 +1376,12 @@ class TOMWrapper:
|
|
|
1393
1376
|
objectType = object.ObjectType
|
|
1394
1377
|
|
|
1395
1378
|
if objectType not in validObjects:
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
)
|
|
1399
|
-
return
|
|
1379
|
+
raise ValueError(f"{icons.red_dot} Only the following object types are valid for perspectives: {validObjects}.")
|
|
1380
|
+
|
|
1400
1381
|
try:
|
|
1401
1382
|
object.Model.Perspectives[perspective_name]
|
|
1402
1383
|
except:
|
|
1403
|
-
|
|
1404
|
-
return
|
|
1384
|
+
raise ValueError(f"{icons.red_dot} The '{perspective_name}' perspective does not exist.")
|
|
1405
1385
|
|
|
1406
1386
|
# try:
|
|
1407
1387
|
if objectType == TOM.ObjectType.Table:
|
|
@@ -1474,8 +1454,7 @@ class TOMWrapper:
|
|
|
1474
1454
|
] # , 'Level'
|
|
1475
1455
|
|
|
1476
1456
|
if object.ObjectType not in validObjects:
|
|
1477
|
-
|
|
1478
|
-
return
|
|
1457
|
+
raise ValueError(f"{icons.red_dot} Translations can only be set to {validObjects}.")
|
|
1479
1458
|
|
|
1480
1459
|
mapping = {
|
|
1481
1460
|
"Name": TOM.TranslatedProperty.Caption,
|
|
@@ -1484,14 +1463,13 @@ class TOMWrapper:
|
|
|
1484
1463
|
}
|
|
1485
1464
|
|
|
1486
1465
|
prop = mapping.get(property)
|
|
1466
|
+
if prop == None:
|
|
1467
|
+
raise ValueError(f"{icons.red_dot} Invalid property value. Please choose from the following: ['Name', 'Description', Display Folder].")
|
|
1487
1468
|
|
|
1488
1469
|
try:
|
|
1489
1470
|
object.Model.Cultures[language]
|
|
1490
1471
|
except:
|
|
1491
|
-
|
|
1492
|
-
f"{icons.red_dot} The '{language}' translation language does not exist in the semantic model."
|
|
1493
|
-
)
|
|
1494
|
-
return
|
|
1472
|
+
raise ValueError(f"{icons.red_dot} The '{language}' translation language does not exist in the semantic model.")
|
|
1495
1473
|
|
|
1496
1474
|
object.Model.Cultures[language].ObjectTranslations.SetTranslation(
|
|
1497
1475
|
object, prop, value
|
|
@@ -1955,11 +1933,8 @@ class TOMWrapper:
|
|
|
1955
1933
|
t = self.model.Tables[table_name]
|
|
1956
1934
|
c = t.Columns[column_name]
|
|
1957
1935
|
if c.DataType != TOM.DataType.DateTime:
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
)
|
|
1961
|
-
return
|
|
1962
|
-
|
|
1936
|
+
raise ValueError(f"{icons.red_dot} The column specified in the 'column_name' parameter in this function must be of DateTime data type.")
|
|
1937
|
+
|
|
1963
1938
|
daxQuery = f"""
|
|
1964
1939
|
define measure '{table_name}'[test] =
|
|
1965
1940
|
var mn = MIN('{table_name}'[{column_name}])
|
|
@@ -1978,10 +1953,7 @@ class TOMWrapper:
|
|
|
1978
1953
|
)
|
|
1979
1954
|
value = df["1"].iloc[0]
|
|
1980
1955
|
if value != "1":
|
|
1981
|
-
|
|
1982
|
-
f"{icons.red_dot} The '{column_name}' within the '{table_name}' table does not contain contiguous date values."
|
|
1983
|
-
)
|
|
1984
|
-
return
|
|
1956
|
+
raise ValueError(f"{icons.red_dot} The '{column_name}' within the '{table_name}' table does not contain contiguous date values.")
|
|
1985
1957
|
|
|
1986
1958
|
# Mark as a date table
|
|
1987
1959
|
t.DataCategory = "Time"
|
|
@@ -2176,10 +2148,7 @@ class TOMWrapper:
|
|
|
2176
2148
|
# https://github.com/m-kovalsky/Tabular/blob/master/KPI%20Graphics.md
|
|
2177
2149
|
|
|
2178
2150
|
if measure_name == target:
|
|
2179
|
-
|
|
2180
|
-
f"{icons.red_dot} The 'target' parameter cannot be the same measure as the 'measure_name' parameter."
|
|
2181
|
-
)
|
|
2182
|
-
return
|
|
2151
|
+
raise ValueError(f"{icons.red_dot} The 'target' parameter cannot be the same measure as the 'measure_name' parameter.")
|
|
2183
2152
|
|
|
2184
2153
|
if status_graphic is None:
|
|
2185
2154
|
status_graphic = "Three Circles Colored"
|
|
@@ -2192,43 +2161,31 @@ class TOMWrapper:
|
|
|
2192
2161
|
status_type = status_type.title().replace(" ", "")
|
|
2193
2162
|
|
|
2194
2163
|
if status_type not in valid_status_types:
|
|
2195
|
-
|
|
2196
|
-
f"{icons.red_dot} '{status_type}' is an invalid status_type. Please choose from these options: {valid_status_types}."
|
|
2197
|
-
)
|
|
2198
|
-
return
|
|
2164
|
+
raise ValueError(f"{icons.red_dot} '{status_type}' is an invalid status_type. Please choose from these options: {valid_status_types}.")
|
|
2199
2165
|
|
|
2200
2166
|
if status_type in ["Linear", "LinearReversed"]:
|
|
2201
2167
|
if upper_bound is not None or lower_mid_bound is not None:
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
)
|
|
2205
|
-
return
|
|
2168
|
+
raise ValueError(f"{icons.red_dot} The 'upper_mid_bound' and 'lower_mid_bound' parameters are not used in the 'Linear' and 'LinearReversed' status types. Make sure these parameters are set to None.")
|
|
2169
|
+
|
|
2206
2170
|
elif upper_bound <= lower_bound:
|
|
2207
|
-
|
|
2208
|
-
return
|
|
2171
|
+
raise ValueError(f"{icons.red_dot} The upper_bound must be greater than the lower_bound.")
|
|
2209
2172
|
|
|
2210
2173
|
if status_type in ["Centered", "CenteredReversed"]:
|
|
2211
2174
|
if upper_mid_bound is None or lower_mid_bound is None:
|
|
2212
|
-
|
|
2213
|
-
f"{icons.red_dot} The 'upper_mid_bound' and 'lower_mid_bound' parameters are necessary in the 'Centered' and 'CenteredReversed' status types."
|
|
2214
|
-
)
|
|
2215
|
-
return
|
|
2175
|
+
raise ValueError(f"{icons.red_dot} The 'upper_mid_bound' and 'lower_mid_bound' parameters are necessary in the 'Centered' and 'CenteredReversed' status types.")
|
|
2216
2176
|
elif upper_bound <= upper_mid_bound:
|
|
2217
|
-
|
|
2177
|
+
raise ValueError(f"{icons.red_dot} The upper_bound must be greater than the upper_mid_bound.")
|
|
2218
2178
|
elif upper_mid_bound <= lower_mid_bound:
|
|
2219
|
-
|
|
2179
|
+
raise ValueError(f"{icons.red_dot} The upper_mid_bound must be greater than the lower_mid_bound.")
|
|
2220
2180
|
elif lower_mid_bound <= lower_bound:
|
|
2221
|
-
|
|
2181
|
+
raise ValueError(f"{icons.red_dot} The lower_mid_bound must be greater than the lower_bound.")
|
|
2222
2182
|
|
|
2223
2183
|
try:
|
|
2224
2184
|
table_name = next(
|
|
2225
2185
|
m.Parent.Name for m in self.all_measures() if m.Name == measure_name
|
|
2226
2186
|
)
|
|
2227
2187
|
except:
|
|
2228
|
-
|
|
2229
|
-
f"{icons.red_dot} The '{measure_name}' measure does not exist in the '{self._dataset}' semantic model within the '{self._workspace}'."
|
|
2230
|
-
)
|
|
2231
|
-
return
|
|
2188
|
+
raise ValueError(f"{icons.red_dot} The '{measure_name}' measure does not exist in the '{self._dataset}' semantic model within the '{self._workspace}'.")
|
|
2232
2189
|
|
|
2233
2190
|
graphics = [
|
|
2234
2191
|
"Cylinder",
|
|
@@ -2251,10 +2208,7 @@ class TOMWrapper:
|
|
|
2251
2208
|
]
|
|
2252
2209
|
|
|
2253
2210
|
if status_graphic not in graphics:
|
|
2254
|
-
|
|
2255
|
-
f"{icons.red_dot} The '{status_graphic}' status graphic is not valid. Please choose from these options: {graphics}."
|
|
2256
|
-
)
|
|
2257
|
-
return
|
|
2211
|
+
raise ValueError(f"{icons.red_dot} The '{status_graphic}' status graphic is not valid. Please choose from these options: {graphics}.")
|
|
2258
2212
|
|
|
2259
2213
|
measure_target = True
|
|
2260
2214
|
|
|
@@ -2270,10 +2224,8 @@ class TOMWrapper:
|
|
|
2270
2224
|
if m.Name == target
|
|
2271
2225
|
)
|
|
2272
2226
|
except:
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
)
|
|
2276
|
-
|
|
2227
|
+
raise ValueError(f"{icons.red_dot} The '{target}' measure does not exist in the '{self._dataset}' semantic model within the '{self._workspace}'.")
|
|
2228
|
+
|
|
2277
2229
|
if measure_target:
|
|
2278
2230
|
expr = f"var x = [{measure_name}]/[{target}]\nreturn"
|
|
2279
2231
|
else:
|
|
@@ -2396,10 +2348,7 @@ class TOMWrapper:
|
|
|
2396
2348
|
)
|
|
2397
2349
|
|
|
2398
2350
|
if value not in values:
|
|
2399
|
-
|
|
2400
|
-
f"{icons.red_dot} '{value}' is not a valid value for the SummarizeBy property. These are the valid values: {values}."
|
|
2401
|
-
)
|
|
2402
|
-
return
|
|
2351
|
+
raise ValueError(f"{icons.red_dot} '{value}' is not a valid value for the SummarizeBy property. These are the valid values: {values}.")
|
|
2403
2352
|
|
|
2404
2353
|
self.model.Tables[table_name].Columns[column_name].SummarizeBy = (
|
|
2405
2354
|
System.Enum.Parse(TOM.AggregateFunction, value)
|
|
@@ -2428,10 +2377,7 @@ class TOMWrapper:
|
|
|
2428
2377
|
dlValues = ["Automatic", "DirectLakeOnly", "DirectQueryOnly"]
|
|
2429
2378
|
|
|
2430
2379
|
if direct_lake_behavior not in dlValues:
|
|
2431
|
-
|
|
2432
|
-
f"{icons.red_dot} The 'direct_lake_behavior' parameter must be one of these values: {dlValues}."
|
|
2433
|
-
)
|
|
2434
|
-
return
|
|
2380
|
+
raise ValueError(f"{icons.red_dot} The 'direct_lake_behavior' parameter must be one of these values: {dlValues}.")
|
|
2435
2381
|
|
|
2436
2382
|
self.model.DirectLakeBehavior = System.Enum.Parse(
|
|
2437
2383
|
TOM.DirectLakeBehavior, direct_lake_behavior
|
|
@@ -2529,13 +2475,10 @@ class TOMWrapper:
|
|
|
2529
2475
|
import Microsoft.AnalysisServices.Tabular as TOM
|
|
2530
2476
|
|
|
2531
2477
|
if isinstance(objects, str):
|
|
2532
|
-
|
|
2533
|
-
|
|
2478
|
+
raise ValueError(f"{icons.red_dot} The 'objects' parameter must be a list of columns/measures.")
|
|
2479
|
+
|
|
2534
2480
|
if len(objects) == 1:
|
|
2535
|
-
|
|
2536
|
-
f"{icons.red_dot} There must be more than one object (column/measure) within the objects parameter."
|
|
2537
|
-
)
|
|
2538
|
-
return
|
|
2481
|
+
raise ValueError(f"{icons.red_dot} There must be more than one object (column/measure) within the objects parameter.")
|
|
2539
2482
|
|
|
2540
2483
|
expr = ""
|
|
2541
2484
|
i = 0
|
|
@@ -2571,10 +2514,7 @@ class TOMWrapper:
|
|
|
2571
2514
|
)
|
|
2572
2515
|
success = True
|
|
2573
2516
|
if not success:
|
|
2574
|
-
|
|
2575
|
-
f"{icons.red_dot} The '{obj}' object was not found in the '{self._dataset}' semantic model."
|
|
2576
|
-
)
|
|
2577
|
-
return
|
|
2517
|
+
raise ValueError(f"{icons.red_dot} The '{obj}' object was not found in the '{self._dataset}' semantic model.")
|
|
2578
2518
|
else:
|
|
2579
2519
|
i += 1
|
|
2580
2520
|
|
|
@@ -3244,26 +3184,16 @@ class TOMWrapper:
|
|
|
3244
3184
|
rolling_window_granularity = rolling_window_granularity.capitalize()
|
|
3245
3185
|
|
|
3246
3186
|
if incremental_granularity not in incGran:
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
)
|
|
3250
|
-
return
|
|
3187
|
+
raise ValueError(f"{icons.red_dot} Invalid 'incremental_granularity' value. Please choose from the following options: {incGran}.")
|
|
3188
|
+
|
|
3251
3189
|
if rolling_window_granularity not in incGran:
|
|
3252
|
-
|
|
3253
|
-
f"{icons.red_dot} Invalid 'rolling_window_granularity' value. Please choose from the following options: {incGran}."
|
|
3254
|
-
)
|
|
3255
|
-
return
|
|
3190
|
+
raise ValueError(f"{icons.red_dot} Invalid 'rolling_window_granularity' value. Please choose from the following options: {incGran}.")
|
|
3256
3191
|
|
|
3257
3192
|
if rolling_window_periods < 1:
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
)
|
|
3261
|
-
return
|
|
3193
|
+
raise ValueError(f"{icons.red_dot} Invalid 'rolling_window_periods' value. Must be a value greater than 0.")
|
|
3194
|
+
|
|
3262
3195
|
if incremental_periods < 1:
|
|
3263
|
-
|
|
3264
|
-
f"{icons.red_dot} Invalid 'incremental_periods' value. Must be a value greater than 0."
|
|
3265
|
-
)
|
|
3266
|
-
return
|
|
3196
|
+
raise ValueError(f"{icons.red_dot} Invalid 'incremental_periods' value. Must be a value greater than 0.")
|
|
3267
3197
|
|
|
3268
3198
|
t = self.model.Tables[table_name]
|
|
3269
3199
|
|
|
@@ -3271,10 +3201,7 @@ class TOMWrapper:
|
|
|
3271
3201
|
dc = t.Columns[detect_data_changes_column]
|
|
3272
3202
|
|
|
3273
3203
|
if dc.DataType != TOM.DataType.DateTime:
|
|
3274
|
-
|
|
3275
|
-
f"{icons.red_dot} Invalid 'detect_data_changes_column' parameter. This column must be of DateTime data type."
|
|
3276
|
-
)
|
|
3277
|
-
return
|
|
3204
|
+
raise ValueError(f"{icons.red_dot} Invalid 'detect_data_changes_column' parameter. This column must be of DateTime data type.")
|
|
3278
3205
|
|
|
3279
3206
|
rp = TOM.BasicRefreshPolicy()
|
|
3280
3207
|
rp.IncrementalPeriods = incremental_periods
|
|
@@ -3354,26 +3281,16 @@ class TOMWrapper:
|
|
|
3354
3281
|
rolling_window_granularity = rolling_window_granularity.capitalize()
|
|
3355
3282
|
|
|
3356
3283
|
if incremental_granularity not in incGran:
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
)
|
|
3360
|
-
return
|
|
3284
|
+
raise ValueError(f"{icons.red_dot} Invalid 'incremental_granularity' value. Please choose from the following options: {incGran}.")
|
|
3285
|
+
|
|
3361
3286
|
if rolling_window_granularity not in incGran:
|
|
3362
|
-
|
|
3363
|
-
f"{icons.red_dot} Invalid 'rolling_window_granularity' value. Please choose from the following options: {incGran}."
|
|
3364
|
-
)
|
|
3365
|
-
return
|
|
3287
|
+
raise ValueError(f"{icons.red_dot} Invalid 'rolling_window_granularity' value. Please choose from the following options: {incGran}.")
|
|
3366
3288
|
|
|
3367
3289
|
if rolling_window_periods < 1:
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
)
|
|
3371
|
-
return
|
|
3290
|
+
raise ValueError(f"{icons.red_dot} Invalid 'rolling_window_periods' value. Must be a value greater than 0.")
|
|
3291
|
+
|
|
3372
3292
|
if incremental_periods < 1:
|
|
3373
|
-
|
|
3374
|
-
f"{icons.red_dot} Invalid 'incremental_periods' value. Must be a value greater than 0."
|
|
3375
|
-
)
|
|
3376
|
-
return
|
|
3293
|
+
raise ValueError(f"{icons.red_dot} Invalid 'incremental_periods' value. Must be a value greater than 0.")
|
|
3377
3294
|
|
|
3378
3295
|
date_format = "%m/%d/%Y"
|
|
3379
3296
|
|
|
@@ -3388,10 +3305,7 @@ class TOMWrapper:
|
|
|
3388
3305
|
end_day = date_obj_end.day
|
|
3389
3306
|
|
|
3390
3307
|
if date_obj_end <= date_obj_start:
|
|
3391
|
-
|
|
3392
|
-
f"{icons.red_dot} Invalid 'start_date' or 'end_date'. The 'end_date' must be after the 'start_date'."
|
|
3393
|
-
)
|
|
3394
|
-
return
|
|
3308
|
+
raise ValueError(f"{icons.red_dot} Invalid 'start_date' or 'end_date'. The 'end_date' must be after the 'start_date'.")
|
|
3395
3309
|
|
|
3396
3310
|
t = self.model.Tables[table_name]
|
|
3397
3311
|
|
|
@@ -3400,20 +3314,14 @@ class TOMWrapper:
|
|
|
3400
3314
|
dType = c.DataType
|
|
3401
3315
|
|
|
3402
3316
|
if dType != TOM.DataType.DateTime:
|
|
3403
|
-
|
|
3404
|
-
f"{icons.red_dot} The {fcName} column is of '{dType}' data type. The column chosen must be of DateTime data type."
|
|
3405
|
-
)
|
|
3406
|
-
return
|
|
3317
|
+
raise ValueError(f"{icons.red_dot} The {fcName} column is of '{dType}' data type. The column chosen must be of DateTime data type.")
|
|
3407
3318
|
|
|
3408
3319
|
if detect_data_changes_column is not None:
|
|
3409
3320
|
dc = t.Columns[detect_data_changes_column]
|
|
3410
3321
|
dcType = dc.DataType
|
|
3411
3322
|
|
|
3412
3323
|
if dcType != TOM.DataType.DateTime:
|
|
3413
|
-
|
|
3414
|
-
f"{icons.red_dot} Invalid 'detect_data_changes_column' parameter. This column must be of DateTime data type."
|
|
3415
|
-
)
|
|
3416
|
-
return
|
|
3324
|
+
raise ValueError(f"{icons.red_dot} Invalid 'detect_data_changes_column' parameter. This column must be of DateTime data type.")
|
|
3417
3325
|
|
|
3418
3326
|
# Start changes:
|
|
3419
3327
|
|
|
@@ -3421,10 +3329,8 @@ class TOMWrapper:
|
|
|
3421
3329
|
i = 0
|
|
3422
3330
|
for p in t.Partitions:
|
|
3423
3331
|
if p.SourceType != TOM.PartitionSourceType.M:
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
)
|
|
3427
|
-
return
|
|
3332
|
+
raise ValueError(f"{icons.red_dot} Invalid partition source type. Incremental refresh can only be set up if the table's partition is an M-partition.")
|
|
3333
|
+
|
|
3428
3334
|
elif i == 0:
|
|
3429
3335
|
text = p.Expression
|
|
3430
3336
|
text = text.rstrip()
|
|
@@ -3440,8 +3346,7 @@ class TOMWrapper:
|
|
|
3440
3346
|
|
|
3441
3347
|
print(text_before_last_match)
|
|
3442
3348
|
else:
|
|
3443
|
-
|
|
3444
|
-
return
|
|
3349
|
+
raise ValueError(f"{icons.red_dot} Invalid M-partition expression.")
|
|
3445
3350
|
|
|
3446
3351
|
endExpr = f'#"Filtered Rows IR" = Table.SelectRows({obj}, each [{column_name}] >= RangeStart and [{column_name}] <= RangeEnd)\n#"Filtered Rows IR"'
|
|
3447
3352
|
finalExpr = text_before_last_match + endExpr
|
|
@@ -3537,15 +3442,9 @@ class TOMWrapper:
|
|
|
3537
3442
|
ht = self.is_hybrid_table(table_name=table_name)
|
|
3538
3443
|
|
|
3539
3444
|
if not ht:
|
|
3540
|
-
|
|
3541
|
-
f"{icons.red_dot} The `data coverage definition <https://learn.microsoft.com/analysis-services/tom/table-partitions?view=asallproducts-allversions>`_ property is only applicable to `hybrid tables <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_. See the documentation: {doc}."
|
|
3542
|
-
)
|
|
3543
|
-
return
|
|
3445
|
+
raise ValueError(f"{icons.red_dot} The `data coverage definition <https://learn.microsoft.com/analysis-services/tom/table-partitions?view=asallproducts-allversions>`_ property is only applicable to `hybrid tables <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_. See the documentation: {doc}.")
|
|
3544
3446
|
if p.Mode != TOM.ModeType.DirectQuery:
|
|
3545
|
-
|
|
3546
|
-
f"{icons.red_dot} The `data coverage definition <https://learn.microsoft.com/analysis-services/tom/table-partitions?view=asallproducts-allversions>`_ property is only applicable to the DirectQuery partition of a `hybrid table <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_. See the documentation: {doc}."
|
|
3547
|
-
)
|
|
3548
|
-
return
|
|
3447
|
+
raise ValueError(f"{icons.red_dot} The `data coverage definition <https://learn.microsoft.com/analysis-services/tom/table-partitions?view=asallproducts-allversions>`_ property is only applicable to the DirectQuery partition of a `hybrid table <https://learn.microsoft.com/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables>`_. See the documentation: {doc}.")
|
|
3549
3448
|
|
|
3550
3449
|
dcd = TOM.DataCoverageDefinition()
|
|
3551
3450
|
dcd.Expression = expression
|
|
@@ -3572,10 +3471,7 @@ class TOMWrapper:
|
|
|
3572
3471
|
value = value.capitalize()
|
|
3573
3472
|
|
|
3574
3473
|
if value not in values:
|
|
3575
|
-
|
|
3576
|
-
f"{icons.red_dot} Invalid encoding hint value. Please choose from these options: {values}."
|
|
3577
|
-
)
|
|
3578
|
-
return
|
|
3474
|
+
raise ValueError(f"{icons.red_dot} Invalid encoding hint value. Please choose from these options: {values}.")
|
|
3579
3475
|
|
|
3580
3476
|
self.model.Tables[table_name].Columns[column_name].EncodingHint = (
|
|
3581
3477
|
System.Enum.Parse(TOM.EncodingHintType, value)
|
|
@@ -3617,10 +3513,7 @@ class TOMWrapper:
|
|
|
3617
3513
|
value = "Boolean"
|
|
3618
3514
|
|
|
3619
3515
|
if value not in values:
|
|
3620
|
-
|
|
3621
|
-
f"{icons.red_dot} Invalid data type. Please choose from these options: {values}."
|
|
3622
|
-
)
|
|
3623
|
-
return
|
|
3516
|
+
raise ValueError(f"{icons.red_dot} Invalid data type. Please choose from these options: {values}.")
|
|
3624
3517
|
|
|
3625
3518
|
self.model.Tables[table_name].Columns[column_name].DataType = System.Enum.Parse(
|
|
3626
3519
|
TOM.DataType, value
|
|
@@ -3652,10 +3545,7 @@ class TOMWrapper:
|
|
|
3652
3545
|
for t in time_intel:
|
|
3653
3546
|
t = t.capitalize()
|
|
3654
3547
|
if t not in [time_intel_options]:
|
|
3655
|
-
|
|
3656
|
-
f"{icons.red_dot} The '{t}' time intelligence variation is not supported. Valid options: {time_intel_options}."
|
|
3657
|
-
)
|
|
3658
|
-
return
|
|
3548
|
+
raise ValueError(f"{icons.red_dot} The '{t}' time intelligence variation is not supported. Valid options: {time_intel_options}.")
|
|
3659
3549
|
|
|
3660
3550
|
# Validate measure and extract table name
|
|
3661
3551
|
for m in self.all_measures():
|
|
@@ -3663,17 +3553,11 @@ class TOMWrapper:
|
|
|
3663
3553
|
table_name = m.Parent.Name
|
|
3664
3554
|
|
|
3665
3555
|
if table_name is None:
|
|
3666
|
-
|
|
3667
|
-
f"{icons.red_dot} The '{measure_name}' is not a valid measure in the '{self._dataset}' semantic model within the '{self._workspace}' workspace."
|
|
3668
|
-
)
|
|
3669
|
-
return
|
|
3556
|
+
raise ValueError(f"{icons.red_dot} The '{measure_name}' is not a valid measure in the '{self._dataset}' semantic model within the '{self._workspace}' workspace.")
|
|
3670
3557
|
|
|
3671
3558
|
# Validate date table
|
|
3672
3559
|
if not self.is_date_table(date_table):
|
|
3673
|
-
|
|
3674
|
-
f"{icons.red_dot} The '{date_table}' table is not a valid date table in the '{self._dataset}' wemantic model within the '{self._workspace}' workspace."
|
|
3675
|
-
)
|
|
3676
|
-
return
|
|
3560
|
+
raise ValueError(f"{icons.red_dot} The '{date_table}' table is not a valid date table in the '{self._dataset}' wemantic model within the '{self._workspace}' workspace.")
|
|
3677
3561
|
|
|
3678
3562
|
# Extract date key from date table
|
|
3679
3563
|
for c in self.all_columns():
|
|
@@ -3691,6 +3575,80 @@ class TOMWrapper:
|
|
|
3691
3575
|
expression=expr,
|
|
3692
3576
|
)
|
|
3693
3577
|
|
|
3578
|
+
def update_m_partition(self, table_name: str, partition_name: str, expression: Optional[str | None] = None, mode: Optional[str | None] = None, description: Optional[str | None] = None):
|
|
3579
|
+
|
|
3580
|
+
"""
|
|
3581
|
+
Updates an M partition for a table within a semantic model.
|
|
3582
|
+
|
|
3583
|
+
Parameters
|
|
3584
|
+
----------
|
|
3585
|
+
table_name : str
|
|
3586
|
+
Name of the table.
|
|
3587
|
+
partition_name : str
|
|
3588
|
+
Name of the partition.
|
|
3589
|
+
expression : str, default=None
|
|
3590
|
+
The `M expression <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.mpartitionsource.expression?view=analysisservices-dotnet>`_ containing the logic for the partition.
|
|
3591
|
+
Defaults to None which keeps the existing setting.
|
|
3592
|
+
mode : str, default=None
|
|
3593
|
+
The query `mode <https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.modetype?view=analysisservices-dotnet>`_ of the partition.
|
|
3594
|
+
Defaults to None which keeps the existing setting.
|
|
3595
|
+
description : str, default=None
|
|
3596
|
+
The description of the partition.
|
|
3597
|
+
Defaults to None which keeps the existing setting.
|
|
3598
|
+
"""
|
|
3599
|
+
|
|
3600
|
+
import Microsoft.AnalysisServices.Tabular as TOM
|
|
3601
|
+
import System
|
|
3602
|
+
|
|
3603
|
+
p = self.model.Tables[table_name].Partitions[partition_name]
|
|
3604
|
+
if p.SourceType != TOM.PartitionSourceType.M:
|
|
3605
|
+
raise ValueError(f"Invalid partition source type. This function is only for M partitions.")
|
|
3606
|
+
if expression is not None:
|
|
3607
|
+
p.Source.Expression = expression
|
|
3608
|
+
if mode is not None:
|
|
3609
|
+
p.Mode = System.Enum.Parse(TOM.ModeType, mode)
|
|
3610
|
+
if description is not None:
|
|
3611
|
+
p.Description = description
|
|
3612
|
+
|
|
3613
|
+
def set_sort_by_column(self, table_name: str, column_name: str, sort_by_column: str):
|
|
3614
|
+
|
|
3615
|
+
"""
|
|
3616
|
+
Sets the sort by column for a column in a semantic model.
|
|
3617
|
+
|
|
3618
|
+
Parameters
|
|
3619
|
+
----------
|
|
3620
|
+
table_name : str
|
|
3621
|
+
Name of the table.
|
|
3622
|
+
column_name : str
|
|
3623
|
+
Name of the column.
|
|
3624
|
+
sort_by_column : str
|
|
3625
|
+
Name of the column to use for sorting. Must be of integer (Int64) data type.
|
|
3626
|
+
"""
|
|
3627
|
+
|
|
3628
|
+
import Microsoft.AnalysisServices.Tabular as TOM
|
|
3629
|
+
|
|
3630
|
+
sbc = self.model.Tables[table_name].Columns[sort_by_column]
|
|
3631
|
+
|
|
3632
|
+
if sbc.DataType != TOM.DataType.Int64:
|
|
3633
|
+
raise ValueError(f"Invalid sort by column data type. The sort by column must be of 'Int64' data type.")
|
|
3634
|
+
|
|
3635
|
+
self.model.Tables[table_name].Columns[column_name].SortByColumn = sbc
|
|
3636
|
+
|
|
3637
|
+
def remove_sort_by_column(self, table_name: str, column_name: str):
|
|
3638
|
+
|
|
3639
|
+
"""
|
|
3640
|
+
Removes the sort by column for a column in a semantic model.
|
|
3641
|
+
|
|
3642
|
+
Parameters
|
|
3643
|
+
----------
|
|
3644
|
+
table_name : str
|
|
3645
|
+
Name of the table.
|
|
3646
|
+
column_name : str
|
|
3647
|
+
Name of the column.
|
|
3648
|
+
"""
|
|
3649
|
+
|
|
3650
|
+
self.model.Tables[table_name].Columns[column_name].SortByColumn = None
|
|
3651
|
+
|
|
3694
3652
|
def close(self):
|
|
3695
3653
|
if not self._readonly and self.model is not None:
|
|
3696
3654
|
self.model.SaveChanges()
|
|
@@ -3742,4 +3700,4 @@ def connect_semantic_model(
|
|
|
3742
3700
|
try:
|
|
3743
3701
|
yield tw
|
|
3744
3702
|
finally:
|
|
3745
|
-
tw.close()
|
|
3703
|
+
tw.close()
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
sempy_labs/__init__.py,sha256=aKnIa8tgtzqT939USn5rjCYnMNRu-Aku4mJSEFG75mc,4126
|
|
2
|
-
sempy_labs/_ai.py,sha256=WXWnVJ9g5Xq5ctiMWFNXbrv2WdAhKv5EsO6tCBy8ceE,17930
|
|
3
|
-
sempy_labs/_clear_cache.py,sha256=yahzQ-QojCtAReFT3zK9lrr5LJhkONUr49GC1qXf6Uw,1476
|
|
4
|
-
sempy_labs/_connections.py,sha256=DNgiMbswZM-vv6qnEnZ2RhIuo1HhGobh47X2UYh2br8,7396
|
|
5
|
-
sempy_labs/_dax.py,sha256=u4qVxsu2dVaOJmso-ErScNZ5yI4lGQTlon_jmrAzvGs,2148
|
|
6
|
-
sempy_labs/_generate_semantic_model.py,sha256=PgqqAk3ptVTXHlW6lU5dqGNZUAOjA3xrqmvZX2GlXx8,9273
|
|
7
|
-
sempy_labs/_helper_functions.py,sha256=mzzMFv6SKottNGBXjBe2-cCTgTQXDf6fXT7MmQ05DLA,14313
|
|
8
|
-
sempy_labs/_icons.py,sha256=mREeT-3eJCAbuKwaYf1IZGWYssy6WQ-mBCZ6nFnKGPU,196
|
|
9
|
-
sempy_labs/_list_functions.py,sha256=mxacAOu2MwBBLqOTbwb_Zqmx6liSItbc8fhQgkxkgqQ,53459
|
|
10
|
-
sempy_labs/_model_auto_build.py,sha256=xv4n4pjBAFAxz9Otu0ggx9QJsgRHzOFf_h4Fyou9p8E,5149
|
|
11
|
-
sempy_labs/_model_bpa.py,sha256=6fvUeZ0isLpmeTF4XC6lK9C5NreIJhoAgWpYIoD236s,63250
|
|
12
|
-
sempy_labs/_model_dependencies.py,sha256=e0QhwQs4KuWllbrYdGQnqQ5YwbbC-KKYxvsqT5x7Y6I,13194
|
|
13
|
-
sempy_labs/_one_lake_integration.py,sha256=RRjyDFitYzsC9vvovlYmvame9lRlV0myABAcFZxYffw,6210
|
|
14
|
-
sempy_labs/_query_scale_out.py,sha256=5X6Q8-hskf6VY_VY02VdyMlmBuV77bHWTTKqMdbGLBg,15296
|
|
15
|
-
sempy_labs/_refresh_semantic_model.py,sha256=YUtSnMyln7_8iPY3owG5uwfm8RqRdCPIKh0fTChuiIM,6805
|
|
16
|
-
sempy_labs/_translations.py,sha256=zW2HmJPqDs5p0Mj-1dTIlgee1rSmfZYMcQoPdNsZCmM,18044
|
|
17
|
-
sempy_labs/_vertipaq.py,sha256=18YT-3zDZnsY9DhPh9iQIjuCW8T91zZjliW8cUtbEAY,33385
|
|
18
|
-
sempy_labs/directlake/__init__.py,sha256=HbfHvDvGE4H-xSbV6JO7TUb4HoLGJf2AeuqeQxIuuJ4,1689
|
|
19
|
-
sempy_labs/directlake/_directlake_schema_compare.py,sha256=1N2NHL9XwjdLz-SPFpGAGkGGFsaEAqAfEdNzfUgli-E,4748
|
|
20
|
-
sempy_labs/directlake/_directlake_schema_sync.py,sha256=Fkg8qJdiPF4ppgG2ED9lN40MbobIleT_W5wCTv190rw,5166
|
|
21
|
-
sempy_labs/directlake/_fallback.py,sha256=StqIL9WS6NWHMIBkgqM14my37Foz_zzkCryZtn_Qjj4,2091
|
|
22
|
-
sempy_labs/directlake/_get_directlake_lakehouse.py,sha256=vEY1QBU7gAdoVQIGl59T_1TTYuXbHgk3pZA41EkVkl8,2358
|
|
23
|
-
sempy_labs/directlake/_get_shared_expression.py,sha256=IyjBSIvmhb5Nri1Xf8QoK8owGFQ2znKP60N0U1VDLg0,2012
|
|
24
|
-
sempy_labs/directlake/_guardrails.py,sha256=NJxT4AStorzNimYIRkLW2iu3T2f_QfGZOhIRdW4glVI,2330
|
|
25
|
-
sempy_labs/directlake/_list_directlake_model_calc_tables.py,sha256=a5YOj3FrMj6DGmnNi9iSriredtti8_802L_Da3pBmrI,2079
|
|
26
|
-
sempy_labs/directlake/_show_unsupported_directlake_objects.py,sha256=9e5RSge91Cg_9qGCUqRlIhq2xvPA_ut_bE20SwZHk50,3386
|
|
27
|
-
sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py,sha256=Qq6iYTvMnimNNa67y3Q_Qpigpez49euK2fNXc05Xg4w,3224
|
|
28
|
-
sempy_labs/directlake/_update_directlake_partition_entity.py,sha256=Egr_NH7XoDDEDc8tz2e3JJ5UKXU0H0EgxTAIcpGr5_M,3207
|
|
29
|
-
sempy_labs/directlake/_warm_cache.py,sha256=fkAw7Lpnoh6dnkdFqtKUeH4fhi6Qzk4ydzHQI-KTqEM,8204
|
|
30
|
-
sempy_labs/lakehouse/__init__.py,sha256=i6VRx4dR1SIN-1GxioiNwhC4FxbozRCIz5TfXjb9rKc,587
|
|
31
|
-
sempy_labs/lakehouse/_get_lakehouse_columns.py,sha256=Ot49AuYtoNwsp-gHWqBplclrSD2rscudwXf_PyFU0mY,2578
|
|
32
|
-
sempy_labs/lakehouse/_get_lakehouse_tables.py,sha256=eUeRloAXC5DUEiPNIwcjyRQRnJID_iDzMqIGZM5QJT0,9094
|
|
33
|
-
sempy_labs/lakehouse/_lakehouse.py,sha256=gkLBpxizTAm-ti8OXqbI9VUgurIG4VjxljxKO3xTtE0,2856
|
|
34
|
-
sempy_labs/lakehouse/_shortcuts.py,sha256=k6p4FMW-tLjGR9vRql7vBQf_bDmNYlax6sf47TUIb34,6910
|
|
35
|
-
sempy_labs/migration/__init__.py,sha256=l5v8pC2INdNwbAKVmvWpuVxs6lpb6omim_4BPOmNo4E,1042
|
|
36
|
-
sempy_labs/migration/_create_pqt_file.py,sha256=MNFxF7XVQBT_-iklsvgm41vG2fyZ0WS42jJ9iFrZVRc,9195
|
|
37
|
-
sempy_labs/migration/_migrate_calctables_to_lakehouse.py,sha256=ajFvHauFdEsbgxvn9JXj2kiXaRtJLEjwX4hWQG7FQy0,20609
|
|
38
|
-
sempy_labs/migration/_migrate_calctables_to_semantic_model.py,sha256=Co2f579vSwkWZ95SlBStS-XJ73YwgcdfAMlJbUv_pkk,6343
|
|
39
|
-
sempy_labs/migration/_migrate_model_objects_to_semantic_model.py,sha256=iCfbyJuharFnHvwviuoRM_caQX8AKmaX47HYafI6Wtg,23955
|
|
40
|
-
sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py,sha256=qohJC6ARjM8NiMH7nZEKqUEXMrh-IqhdeUzgrBNZ1DQ,7028
|
|
41
|
-
sempy_labs/migration/_migration_validation.py,sha256=IdSNuK2EVz-egX7glvcocvRlWZrnKj5_nOz-l20yZdk,2370
|
|
42
|
-
sempy_labs/migration/_refresh_calc_tables.py,sha256=MjtBBoDA8W6J-6HPD736Voocp5AK2E1glXCy79C57ts,5985
|
|
43
|
-
sempy_labs/report/__init__.py,sha256=fkjbkAXZuH7VnAn-k3iB4dngWZKaX-k0bxS6mBa9iAs,846
|
|
44
|
-
sempy_labs/report/_generate_report.py,sha256=D1u_XzbvgYzUO4NXU5k9huMNh0n7bEjreW4SSoaa2vE,8532
|
|
45
|
-
sempy_labs/report/_report_functions.py,sha256=Ctx9kCTOC40ibBvkzGt2DAZG9GNa_iE8_T4ruERsk7A,30016
|
|
46
|
-
sempy_labs/report/_report_rebind.py,sha256=sWaj6aw8sh0njZ0__ULeGD4CZrg7oPLKtOlv4ETKGOk,4635
|
|
47
|
-
sempy_labs/tom/__init__.py,sha256=hFwkmWk5AZ7GK1LWqoqaK1g4gDmu9mZMkfLQvLsR_eE,130
|
|
48
|
-
sempy_labs/tom/_model.py,sha256=hRnIL1rkdYBTFt3hg2zcsEmvsoMhUCAeepmFyzyfzhA,135257
|
|
49
|
-
semantic_link_labs-0.4.2.dist-info/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
|
|
50
|
-
semantic_link_labs-0.4.2.dist-info/METADATA,sha256=d4DjYbKoZum30lR9bqhV-X1CHR5DZCfsdnay1UOz-w4,764
|
|
51
|
-
semantic_link_labs-0.4.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
52
|
-
semantic_link_labs-0.4.2.dist-info/top_level.txt,sha256=kiQX1y42Dbein1l3Q8jMUYyRulDjdlc2tMepvtrvixQ,11
|
|
53
|
-
semantic_link_labs-0.4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|