semantic-link-labs 0.4.1__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.1.dist-info/LICENSE +21 -0
- semantic_link_labs-0.4.1.dist-info/METADATA +22 -0
- semantic_link_labs-0.4.1.dist-info/RECORD +52 -0
- semantic_link_labs-0.4.1.dist-info/WHEEL +5 -0
- semantic_link_labs-0.4.1.dist-info/top_level.txt +1 -0
- sempy_labs/__init__.py +154 -0
- sempy_labs/_ai.py +496 -0
- sempy_labs/_clear_cache.py +39 -0
- sempy_labs/_connections.py +234 -0
- sempy_labs/_dax.py +70 -0
- sempy_labs/_generate_semantic_model.py +280 -0
- sempy_labs/_helper_functions.py +506 -0
- sempy_labs/_icons.py +4 -0
- sempy_labs/_list_functions.py +1372 -0
- sempy_labs/_model_auto_build.py +143 -0
- sempy_labs/_model_bpa.py +1354 -0
- sempy_labs/_model_dependencies.py +341 -0
- sempy_labs/_one_lake_integration.py +155 -0
- sempy_labs/_query_scale_out.py +447 -0
- sempy_labs/_refresh_semantic_model.py +184 -0
- sempy_labs/_tom.py +3766 -0
- sempy_labs/_translations.py +378 -0
- sempy_labs/_vertipaq.py +893 -0
- sempy_labs/directlake/__init__.py +45 -0
- sempy_labs/directlake/_directlake_schema_compare.py +110 -0
- sempy_labs/directlake/_directlake_schema_sync.py +128 -0
- sempy_labs/directlake/_fallback.py +62 -0
- sempy_labs/directlake/_get_directlake_lakehouse.py +69 -0
- sempy_labs/directlake/_get_shared_expression.py +59 -0
- sempy_labs/directlake/_guardrails.py +84 -0
- sempy_labs/directlake/_list_directlake_model_calc_tables.py +54 -0
- sempy_labs/directlake/_show_unsupported_directlake_objects.py +89 -0
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +81 -0
- sempy_labs/directlake/_update_directlake_partition_entity.py +64 -0
- sempy_labs/directlake/_warm_cache.py +210 -0
- sempy_labs/lakehouse/__init__.py +24 -0
- sempy_labs/lakehouse/_get_lakehouse_columns.py +81 -0
- sempy_labs/lakehouse/_get_lakehouse_tables.py +250 -0
- sempy_labs/lakehouse/_lakehouse.py +85 -0
- sempy_labs/lakehouse/_shortcuts.py +296 -0
- sempy_labs/migration/__init__.py +29 -0
- sempy_labs/migration/_create_pqt_file.py +239 -0
- sempy_labs/migration/_migrate_calctables_to_lakehouse.py +429 -0
- sempy_labs/migration/_migrate_calctables_to_semantic_model.py +150 -0
- sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +524 -0
- sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +165 -0
- sempy_labs/migration/_migration_validation.py +227 -0
- sempy_labs/migration/_refresh_calc_tables.py +129 -0
- sempy_labs/report/__init__.py +35 -0
- sempy_labs/report/_generate_report.py +253 -0
- sempy_labs/report/_report_functions.py +855 -0
- sempy_labs/report/_report_rebind.py +131 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from typing import List, Optional, Union
|
|
3
|
+
from sempy._utils._log import log
|
|
4
|
+
import sempy_labs._icons as icons
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@log
|
|
8
|
+
def translate_semantic_model(
|
|
9
|
+
dataset: str,
|
|
10
|
+
languages: Union[str, List[str]],
|
|
11
|
+
exclude_characters: Optional[str] = None,
|
|
12
|
+
workspace: Optional[str] = None,
|
|
13
|
+
):
|
|
14
|
+
"""
|
|
15
|
+
Translates names, descriptions, display folders for all objects in a semantic model.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
dataset : str
|
|
20
|
+
Name of the semantic model.
|
|
21
|
+
languages : str, List[str]
|
|
22
|
+
The language code(s) in which to translate the semantic model.
|
|
23
|
+
exclude_characters : str
|
|
24
|
+
A string specifying characters which will be replaced by a space in the translation text when sent to the translation service.
|
|
25
|
+
workspace : str, default=None
|
|
26
|
+
The Fabric workspace name.
|
|
27
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
28
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from synapse.ml.services import Translate
|
|
36
|
+
from pyspark.sql.functions import col, flatten
|
|
37
|
+
from pyspark.sql import SparkSession
|
|
38
|
+
from ._tom import connect_semantic_model
|
|
39
|
+
|
|
40
|
+
if isinstance(languages, str):
|
|
41
|
+
languages = [languages]
|
|
42
|
+
|
|
43
|
+
dfPrep = pd.DataFrame(
|
|
44
|
+
columns=["Object Type", "Name", "Description", "Display Folder"]
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
with connect_semantic_model(
|
|
48
|
+
dataset=dataset, readonly=False, workspace=workspace
|
|
49
|
+
) as tom:
|
|
50
|
+
|
|
51
|
+
if exclude_characters is None:
|
|
52
|
+
for o in tom.model.Tables:
|
|
53
|
+
new_data = {
|
|
54
|
+
"Object Type": "Table",
|
|
55
|
+
"Name": o.Name,
|
|
56
|
+
"TName": o.Name,
|
|
57
|
+
"Description": o.Description,
|
|
58
|
+
"TDescription": o.Description,
|
|
59
|
+
"Display Folder": None,
|
|
60
|
+
"TDisplay Folder": None,
|
|
61
|
+
}
|
|
62
|
+
dfPrep = pd.concat(
|
|
63
|
+
[dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
64
|
+
)
|
|
65
|
+
for o in tom.all_columns():
|
|
66
|
+
new_data = {
|
|
67
|
+
"Object Type": "Column",
|
|
68
|
+
"Name": o.Name,
|
|
69
|
+
"TName": o.Name,
|
|
70
|
+
"Description": o.Description,
|
|
71
|
+
"TDescription": o.Description,
|
|
72
|
+
"Display Folder": o.DisplayFolder,
|
|
73
|
+
"TDisplay Folder": o.DisplayFolder,
|
|
74
|
+
}
|
|
75
|
+
dfPrep = pd.concat(
|
|
76
|
+
[dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
77
|
+
)
|
|
78
|
+
for o in tom.all_measures():
|
|
79
|
+
new_data = {
|
|
80
|
+
"Object Type": "Measure",
|
|
81
|
+
"Name": o.Name,
|
|
82
|
+
"TName": o.Name,
|
|
83
|
+
"Description": o.Description,
|
|
84
|
+
"TDescription": o.Description,
|
|
85
|
+
"Display Folder": o.DisplayFolder,
|
|
86
|
+
"TDisplay Folder": o.DisplayFolder,
|
|
87
|
+
}
|
|
88
|
+
dfPrep = pd.concat(
|
|
89
|
+
[dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
90
|
+
)
|
|
91
|
+
for o in tom.all_hierarchies():
|
|
92
|
+
new_data = {
|
|
93
|
+
"Object Type": "Hierarchy",
|
|
94
|
+
"Name": o.Name,
|
|
95
|
+
"TName": o.Name,
|
|
96
|
+
"Description": o.Description,
|
|
97
|
+
"TDescription": o.Description,
|
|
98
|
+
"Display Folder": o.DisplayFolder,
|
|
99
|
+
"TDisplay Folder": o.DisplayFolder,
|
|
100
|
+
}
|
|
101
|
+
dfPrep = pd.concat(
|
|
102
|
+
[dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
for o in tom.model.Tables:
|
|
106
|
+
oName = o.Name
|
|
107
|
+
oDescription = o.Description
|
|
108
|
+
for s in exclude_characters:
|
|
109
|
+
oName = oName.replace(s, " ")
|
|
110
|
+
oDescription = oDescription.replace(s, " ")
|
|
111
|
+
new_data = {
|
|
112
|
+
"Object Type": "Table",
|
|
113
|
+
"Name": o.Name,
|
|
114
|
+
"TName": oName,
|
|
115
|
+
"Description": o.Description,
|
|
116
|
+
"TDescription": oDescription,
|
|
117
|
+
"Display Folder": None,
|
|
118
|
+
"TDisplay Folder": None,
|
|
119
|
+
}
|
|
120
|
+
dfPrep = pd.concat(
|
|
121
|
+
[dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
122
|
+
)
|
|
123
|
+
for o in tom.all_columns():
|
|
124
|
+
oName = o.Name
|
|
125
|
+
oDescription = o.Description
|
|
126
|
+
oDisplayFolder = o.DisplayFolder
|
|
127
|
+
for s in exclude_characters:
|
|
128
|
+
oName = oName.replace(s, " ")
|
|
129
|
+
oDescription = oDescription.replace(s, " ")
|
|
130
|
+
oDisplayFolder = oDisplayFolder.replace(s, " ")
|
|
131
|
+
new_data = {
|
|
132
|
+
"Object Type": "Column",
|
|
133
|
+
"Name": o.Name,
|
|
134
|
+
"TName": oName,
|
|
135
|
+
"Description": o.Description,
|
|
136
|
+
"TDescription": oDescription,
|
|
137
|
+
"Display Folder": o.DisplayFolder,
|
|
138
|
+
"TDisplay Folder": oDisplayFolder,
|
|
139
|
+
}
|
|
140
|
+
dfPrep = pd.concat(
|
|
141
|
+
[dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
142
|
+
)
|
|
143
|
+
for o in tom.all_measures():
|
|
144
|
+
oName = o.Name
|
|
145
|
+
oDescription = o.Description
|
|
146
|
+
oDisplayFolder = o.DisplayFolder
|
|
147
|
+
for s in exclude_characters:
|
|
148
|
+
oName = oName.replace(s, " ")
|
|
149
|
+
oDescription = oDescription.replace(s, " ")
|
|
150
|
+
oDisplayFolder = oDisplayFolder.replace(s, " ")
|
|
151
|
+
new_data = {
|
|
152
|
+
"Object Type": "Measure",
|
|
153
|
+
"Name": o.Name,
|
|
154
|
+
"TName": oName,
|
|
155
|
+
"Description": o.Description,
|
|
156
|
+
"TDescription": oDescription,
|
|
157
|
+
"Display Folder": o.DisplayFolder,
|
|
158
|
+
"TDisplay Folder": oDisplayFolder,
|
|
159
|
+
}
|
|
160
|
+
dfPrep = pd.concat(
|
|
161
|
+
[dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
162
|
+
)
|
|
163
|
+
for o in tom.all_hierarchies():
|
|
164
|
+
oName = o.Name
|
|
165
|
+
oDescription = o.Description
|
|
166
|
+
oDisplayFolder = o.DisplayFolder
|
|
167
|
+
for s in exclude_characters:
|
|
168
|
+
oName = oName.replace(s, " ")
|
|
169
|
+
oDescription = oDescription.replace(s, " ")
|
|
170
|
+
oDisplayFolder = oDisplayFolder.replace(s, " ")
|
|
171
|
+
new_data = {
|
|
172
|
+
"Object Type": "Hierarchy",
|
|
173
|
+
"Name": o.Name,
|
|
174
|
+
"TName": oName,
|
|
175
|
+
"Description": o.Description,
|
|
176
|
+
"TDescription": oDescription,
|
|
177
|
+
"Display Folder": o.DisplayFolder,
|
|
178
|
+
"TDisplay Folder": oDisplayFolder,
|
|
179
|
+
}
|
|
180
|
+
dfPrep = pd.concat(
|
|
181
|
+
[dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
spark = SparkSession.builder.getOrCreate()
|
|
185
|
+
df = spark.createDataFrame(dfPrep)
|
|
186
|
+
|
|
187
|
+
columns = ["Name", "Description", "Display Folder"]
|
|
188
|
+
|
|
189
|
+
for clm in columns:
|
|
190
|
+
columnToTranslate = f"T{clm}"
|
|
191
|
+
translate = (
|
|
192
|
+
Translate()
|
|
193
|
+
.setTextCol(columnToTranslate)
|
|
194
|
+
.setToLanguage(languages)
|
|
195
|
+
.setOutputCol("translation")
|
|
196
|
+
.setConcurrency(5)
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
transDF = (
|
|
200
|
+
translate.transform(df)
|
|
201
|
+
.withColumn("translation", flatten(col("translation.translations")))
|
|
202
|
+
.withColumn("translation", col("translation.text"))
|
|
203
|
+
.select("Object Type", clm, columnToTranslate, "translation")
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
df_panda = transDF.toPandas()
|
|
207
|
+
print(f"{icons.in_progress} Translating {clm}s...")
|
|
208
|
+
|
|
209
|
+
for lang in languages:
|
|
210
|
+
i = languages.index(lang)
|
|
211
|
+
tom.add_translation(language=lang)
|
|
212
|
+
print(f"{icons.in_progress} Translating into the '{lang}' language...")
|
|
213
|
+
|
|
214
|
+
for t in tom.model.Tables:
|
|
215
|
+
if t.IsHidden == False:
|
|
216
|
+
if clm == "Name":
|
|
217
|
+
df_filt = df_panda[
|
|
218
|
+
(df_panda["Object Type"] == "Table")
|
|
219
|
+
& (df_panda["Name"] == t.Name)
|
|
220
|
+
]
|
|
221
|
+
if len(df_filt) == 1:
|
|
222
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
223
|
+
tom.set_translation(
|
|
224
|
+
object=t, language=lang, property="Name", value=tr
|
|
225
|
+
)
|
|
226
|
+
print(
|
|
227
|
+
f"{icons.green_dot} Translation '{tr}' set for the '{lang}' language on the '{t.Name}' table."
|
|
228
|
+
)
|
|
229
|
+
elif clm == "Description" and t.Description is not None:
|
|
230
|
+
df_filt = df_panda[
|
|
231
|
+
(df_panda["Object Type"] == "Table")
|
|
232
|
+
& (df_panda["Description"] == t.Description)
|
|
233
|
+
]
|
|
234
|
+
if len(df_filt) == 1:
|
|
235
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
236
|
+
tom.set_translation(
|
|
237
|
+
object=t,
|
|
238
|
+
language=lang,
|
|
239
|
+
property="Description",
|
|
240
|
+
value=tr,
|
|
241
|
+
)
|
|
242
|
+
for c in t.Columns:
|
|
243
|
+
if c.IsHidden == False:
|
|
244
|
+
if clm == "Name":
|
|
245
|
+
df_filt = df_panda[
|
|
246
|
+
(df_panda["Object Type"] == "Column")
|
|
247
|
+
& (df_panda["Name"] == c.Name)
|
|
248
|
+
]
|
|
249
|
+
if len(df_filt) == 1:
|
|
250
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
251
|
+
tom.set_translation(
|
|
252
|
+
object=c,
|
|
253
|
+
language=lang,
|
|
254
|
+
property="Name",
|
|
255
|
+
value=tr,
|
|
256
|
+
)
|
|
257
|
+
print(
|
|
258
|
+
f"{icons.green_dot} Translation '{tr}' set on the '{c.Name}' column within the {t.Name}' table."
|
|
259
|
+
)
|
|
260
|
+
elif clm == "Description" and c.Description is not None:
|
|
261
|
+
df_filt = df_panda[
|
|
262
|
+
(df_panda["Object Type"] == "Column")
|
|
263
|
+
& (df_panda["Description"] == c.Description)
|
|
264
|
+
]
|
|
265
|
+
if len(df_filt) == 1:
|
|
266
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
267
|
+
tom.set_translation(
|
|
268
|
+
object=c,
|
|
269
|
+
language=lang,
|
|
270
|
+
property="Description",
|
|
271
|
+
value=tr,
|
|
272
|
+
)
|
|
273
|
+
elif (
|
|
274
|
+
clm == "Display Folder"
|
|
275
|
+
and c.DisplayFolder is not None
|
|
276
|
+
):
|
|
277
|
+
df_filt = df_panda[
|
|
278
|
+
(df_panda["Object Type"] == "Column")
|
|
279
|
+
& (df_panda["Display Folder"] == c.Description)
|
|
280
|
+
]
|
|
281
|
+
if len(df_filt) == 1:
|
|
282
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
283
|
+
tom.set_translation(
|
|
284
|
+
object=c,
|
|
285
|
+
language=lang,
|
|
286
|
+
property="Display Folder",
|
|
287
|
+
value=tr,
|
|
288
|
+
)
|
|
289
|
+
for h in t.Hierarchies:
|
|
290
|
+
if h.IsHidden == False:
|
|
291
|
+
if clm == "Name":
|
|
292
|
+
df_filt = df_panda[
|
|
293
|
+
(df_panda["Object Type"] == "Hierarchy")
|
|
294
|
+
& (df_panda["Name"] == h.Name)
|
|
295
|
+
]
|
|
296
|
+
if len(df_filt) == 1:
|
|
297
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
298
|
+
tom.set_translation(
|
|
299
|
+
object=h,
|
|
300
|
+
language=lang,
|
|
301
|
+
property="Name",
|
|
302
|
+
value=tr,
|
|
303
|
+
)
|
|
304
|
+
elif clm == "Description" and h.Description is not None:
|
|
305
|
+
df_filt = df_panda[
|
|
306
|
+
(df_panda["Object Type"] == "Hierarchy")
|
|
307
|
+
& (df_panda["Description"] == h.Description)
|
|
308
|
+
]
|
|
309
|
+
if len(df_filt) == 1:
|
|
310
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
311
|
+
tom.set_translation(
|
|
312
|
+
object=h,
|
|
313
|
+
language=lang,
|
|
314
|
+
property="Description",
|
|
315
|
+
value=tr,
|
|
316
|
+
)
|
|
317
|
+
elif (
|
|
318
|
+
clm == "Display Folder"
|
|
319
|
+
and h.DisplayFolder is not None
|
|
320
|
+
):
|
|
321
|
+
df_filt = df_panda[
|
|
322
|
+
(df_panda["Object Type"] == "Hierarchy")
|
|
323
|
+
& (df_panda["Display Folder"] == h.Description)
|
|
324
|
+
]
|
|
325
|
+
if len(df_filt) == 1:
|
|
326
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
327
|
+
tom.set_translation(
|
|
328
|
+
object=h,
|
|
329
|
+
language=lang,
|
|
330
|
+
property="Display Folder",
|
|
331
|
+
value=tr,
|
|
332
|
+
)
|
|
333
|
+
for ms in t.Measures:
|
|
334
|
+
if ms.IsHidden == False:
|
|
335
|
+
if clm == "Name":
|
|
336
|
+
df_filt = df_panda[
|
|
337
|
+
(df_panda["Object Type"] == "Measure")
|
|
338
|
+
& (df_panda["Name"] == ms.Name)
|
|
339
|
+
]
|
|
340
|
+
if len(df_filt) == 1:
|
|
341
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
342
|
+
tom.set_translation(
|
|
343
|
+
object=ms,
|
|
344
|
+
language=lang,
|
|
345
|
+
property="Name",
|
|
346
|
+
value=tr,
|
|
347
|
+
)
|
|
348
|
+
print(
|
|
349
|
+
f"{icons.green_dot} Translation '{tr}' set on the '{ms.Name}' column within the {t.Name}' table."
|
|
350
|
+
)
|
|
351
|
+
elif clm == "Description" and ms.Description is not None:
|
|
352
|
+
df_filt = df_panda[
|
|
353
|
+
(df_panda["Object Type"] == "Measure")
|
|
354
|
+
& (df_panda["Description"] == ms.Description)
|
|
355
|
+
]
|
|
356
|
+
if len(df_filt) == 1:
|
|
357
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
358
|
+
tom.set_translation(
|
|
359
|
+
object=ms,
|
|
360
|
+
language=lang,
|
|
361
|
+
property="Description",
|
|
362
|
+
value=tr,
|
|
363
|
+
)
|
|
364
|
+
elif (
|
|
365
|
+
clm == "Display Folder" and ms.DisplayFolder is not None
|
|
366
|
+
):
|
|
367
|
+
df_filt = df_panda[
|
|
368
|
+
(df_panda["Object Type"] == "Measure")
|
|
369
|
+
& (df_panda["Display Folder"] == ms.Description)
|
|
370
|
+
]
|
|
371
|
+
if len(df_filt) == 1:
|
|
372
|
+
tr = df_filt["translation"].str[i].iloc[0]
|
|
373
|
+
tom.set_translation(
|
|
374
|
+
object=ms,
|
|
375
|
+
language=lang,
|
|
376
|
+
property="Display Folder",
|
|
377
|
+
value=tr,
|
|
378
|
+
)
|