semantic-link-labs 0.7.3__py3-none-any.whl → 0.8.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.

Files changed (75) hide show
  1. {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/METADATA +19 -4
  2. {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/RECORD +75 -50
  3. {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +109 -31
  5. sempy_labs/_bpa_translation/{_translations_am-ET.po → _model/_translations_am-ET.po} +22 -0
  6. sempy_labs/_bpa_translation/{_translations_ar-AE.po → _model/_translations_ar-AE.po} +24 -0
  7. sempy_labs/_bpa_translation/_model/_translations_bg-BG.po +938 -0
  8. sempy_labs/_bpa_translation/_model/_translations_ca-ES.po +934 -0
  9. sempy_labs/_bpa_translation/{_translations_cs-CZ.po → _model/_translations_cs-CZ.po} +179 -157
  10. sempy_labs/_bpa_translation/{_translations_da-DK.po → _model/_translations_da-DK.po} +24 -0
  11. sempy_labs/_bpa_translation/{_translations_de-DE.po → _model/_translations_de-DE.po} +77 -52
  12. sempy_labs/_bpa_translation/{_translations_el-GR.po → _model/_translations_el-GR.po} +25 -0
  13. sempy_labs/_bpa_translation/{_translations_es-ES.po → _model/_translations_es-ES.po} +67 -43
  14. sempy_labs/_bpa_translation/{_translations_fa-IR.po → _model/_translations_fa-IR.po} +24 -0
  15. sempy_labs/_bpa_translation/_model/_translations_fi-FI.po +915 -0
  16. sempy_labs/_bpa_translation/{_translations_fr-FR.po → _model/_translations_fr-FR.po} +83 -57
  17. sempy_labs/_bpa_translation/{_translations_ga-IE.po → _model/_translations_ga-IE.po} +25 -0
  18. sempy_labs/_bpa_translation/{_translations_he-IL.po → _model/_translations_he-IL.po} +23 -0
  19. sempy_labs/_bpa_translation/{_translations_hi-IN.po → _model/_translations_hi-IN.po} +24 -0
  20. sempy_labs/_bpa_translation/{_translations_hu-HU.po → _model/_translations_hu-HU.po} +25 -0
  21. sempy_labs/_bpa_translation/_model/_translations_id-ID.po +918 -0
  22. sempy_labs/_bpa_translation/{_translations_is-IS.po → _model/_translations_is-IS.po} +25 -0
  23. sempy_labs/_bpa_translation/{_translations_it-IT.po → _model/_translations_it-IT.po} +25 -0
  24. sempy_labs/_bpa_translation/{_translations_ja-JP.po → _model/_translations_ja-JP.po} +21 -0
  25. sempy_labs/_bpa_translation/_model/_translations_ko-KR.po +823 -0
  26. sempy_labs/_bpa_translation/_model/_translations_mt-MT.po +937 -0
  27. sempy_labs/_bpa_translation/{_translations_nl-NL.po → _model/_translations_nl-NL.po} +80 -56
  28. sempy_labs/_bpa_translation/{_translations_pl-PL.po → _model/_translations_pl-PL.po} +101 -76
  29. sempy_labs/_bpa_translation/{_translations_pt-BR.po → _model/_translations_pt-BR.po} +25 -0
  30. sempy_labs/_bpa_translation/{_translations_pt-PT.po → _model/_translations_pt-PT.po} +25 -0
  31. sempy_labs/_bpa_translation/_model/_translations_ro-RO.po +939 -0
  32. sempy_labs/_bpa_translation/{_translations_ru-RU.po → _model/_translations_ru-RU.po} +25 -0
  33. sempy_labs/_bpa_translation/_model/_translations_sk-SK.po +925 -0
  34. sempy_labs/_bpa_translation/_model/_translations_sl-SL.po +922 -0
  35. sempy_labs/_bpa_translation/{_translations_ta-IN.po → _model/_translations_ta-IN.po} +26 -0
  36. sempy_labs/_bpa_translation/{_translations_te-IN.po → _model/_translations_te-IN.po} +24 -0
  37. sempy_labs/_bpa_translation/{_translations_th-TH.po → _model/_translations_th-TH.po} +24 -0
  38. sempy_labs/_bpa_translation/_model/_translations_tr-TR.po +925 -0
  39. sempy_labs/_bpa_translation/_model/_translations_uk-UA.po +933 -0
  40. sempy_labs/_bpa_translation/{_translations_zh-CN.po → _model/_translations_zh-CN.po} +116 -97
  41. sempy_labs/_bpa_translation/{_translations_zu-ZA.po → _model/_translations_zu-ZA.po} +25 -0
  42. sempy_labs/_capacities.py +577 -0
  43. sempy_labs/_capacity_migration.py +624 -0
  44. sempy_labs/_clear_cache.py +8 -8
  45. sempy_labs/_connections.py +140 -0
  46. sempy_labs/_environments.py +156 -0
  47. sempy_labs/_git.py +20 -21
  48. sempy_labs/_helper_functions.py +151 -10
  49. sempy_labs/_icons.py +62 -0
  50. sempy_labs/_list_functions.py +232 -887
  51. sempy_labs/_model_bpa.py +8 -32
  52. sempy_labs/_notebooks.py +143 -0
  53. sempy_labs/_query_scale_out.py +30 -8
  54. sempy_labs/_spark.py +460 -0
  55. sempy_labs/_sql.py +88 -19
  56. sempy_labs/_translations.py +3 -0
  57. sempy_labs/_vertipaq.py +162 -99
  58. sempy_labs/_workspaces.py +294 -0
  59. sempy_labs/admin/__init__.py +53 -0
  60. sempy_labs/admin/_basic_functions.py +806 -0
  61. sempy_labs/admin/_domains.py +411 -0
  62. sempy_labs/directlake/_directlake_schema_sync.py +1 -2
  63. sempy_labs/directlake/_generate_shared_expression.py +11 -14
  64. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +14 -24
  65. sempy_labs/report/__init__.py +9 -6
  66. sempy_labs/report/_report_bpa.py +359 -0
  67. sempy_labs/report/_report_bpa_rules.py +113 -0
  68. sempy_labs/report/_report_helper.py +254 -0
  69. sempy_labs/report/_report_list_functions.py +95 -0
  70. sempy_labs/report/_report_rebind.py +0 -4
  71. sempy_labs/report/_reportwrapper.py +2039 -0
  72. sempy_labs/tom/_model.py +83 -5
  73. {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/LICENSE +0 -0
  74. {semantic_link_labs-0.7.3.dist-info → semantic_link_labs-0.8.0.dist-info}/top_level.txt +0 -0
  75. /sempy_labs/_bpa_translation/{_translations_sv-SE.po → _model/_translations_sv-SE.po} +0 -0
@@ -1,6 +1,146 @@
1
1
  import sempy.fabric as fabric
2
2
  import pandas as pd
3
3
  from sempy.fabric.exceptions import FabricHTTPException
4
+ from typing import Optional
5
+ from sempy_labs._helper_functions import pagination
6
+
7
+
8
+ def list_connections() -> pd.DataFrame:
9
+ """
10
+ Lists all available connections.
11
+
12
+ Returns
13
+ -------
14
+ pandas.DataFrame
15
+ A pandas dataframe showing all available connections.
16
+ """
17
+
18
+ client = fabric.FabricRestClient()
19
+ response = client.get("/v1/connections")
20
+
21
+ if response.status_code != 200:
22
+ raise FabricHTTPException(response)
23
+
24
+ df = pd.DataFrame(
25
+ columns=[
26
+ "Connection Id",
27
+ "Connection Name",
28
+ "Gateway Id",
29
+ "Connectivity Type",
30
+ "Connection Path",
31
+ "Connection Type",
32
+ "Privacy Level",
33
+ "Credential Type",
34
+ "Single Sign on Type",
35
+ "Connection Encyrption",
36
+ "Skip Test Connection",
37
+ ]
38
+ )
39
+
40
+ for i in response.json().get("value", []):
41
+ connection_details = i.get("connectionDetails", {})
42
+ credential_details = i.get("credentialDetails", {})
43
+
44
+ new_data = {
45
+ "Connection Id": i.get("id"),
46
+ "Connection Name": i.get("displayName"),
47
+ "Gateway Id": i.get("gatewayId"),
48
+ "Connectivity Type": i.get("connectivityType"),
49
+ "Connection Path": connection_details.get("path"),
50
+ "Connection Type": connection_details.get("type"),
51
+ "Privacy Level": i.get("privacyLevel"),
52
+ "Credential Type": (
53
+ credential_details.get("credentialType") if credential_details else None
54
+ ),
55
+ "Single Sign On Type": (
56
+ credential_details.get("singleSignOnType")
57
+ if credential_details
58
+ else None
59
+ ),
60
+ "Connection Encryption": (
61
+ credential_details.get("connectionEncryption")
62
+ if credential_details
63
+ else None
64
+ ),
65
+ "Skip Test Connection": (
66
+ credential_details.get("skipTestConnection")
67
+ if credential_details
68
+ else None
69
+ ),
70
+ }
71
+
72
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
73
+ bool_cols = ["Skip Test Connection"]
74
+ df[bool_cols] = df[bool_cols].astype(bool)
75
+
76
+ return df
77
+
78
+
79
+ def list_item_connections(
80
+ item_name: str, item_type: str, workspace: Optional[str] = None
81
+ ) -> pd.DataFrame:
82
+ """
83
+ Shows the list of connections that the specified item is connected to.
84
+
85
+ Parameters
86
+ ----------
87
+ item_name : str
88
+ The item name.
89
+ item_type : str
90
+ The `item type <https://learn.microsoft.com/rest/api/fabric/core/items/update-item?tabs=HTTP#itemtype>`_.
91
+ workspace : str, default=None
92
+ The Fabric workspace name.
93
+ Defaults to None which resolves to the workspace of the attached lakehouse
94
+ or if no lakehouse attached, resolves to the workspace of the notebook.
95
+
96
+ Returns
97
+ -------
98
+ pandas.DataFrame
99
+ A pandas dataframe showing the list of connections that the specified item is connected to.
100
+ """
101
+
102
+ # https://learn.microsoft.com/en-us/rest/api/fabric/core/items/list-item-connections?tabs=HTTP
103
+
104
+ workspace = fabric.resolve_workspace_name(workspace)
105
+ workspace_id = fabric.resolve_workspace_id(workspace)
106
+ item_type = item_type[0].upper() + item_type[1:]
107
+ item_id = fabric.resolve_item_id(
108
+ item_name=item_name, type=item_type, workspace=workspace
109
+ )
110
+
111
+ client = fabric.FabricRestClient()
112
+ response = client.post(f"/v1/workspaces/{workspace_id}/items/{item_id}/connections")
113
+
114
+ df = pd.DataFrame(
115
+ columns=[
116
+ "Connection Name",
117
+ "Connection Id",
118
+ "Connectivity Type",
119
+ "Connection Type",
120
+ "Connection Path",
121
+ "Gateway Id",
122
+ ]
123
+ )
124
+
125
+ if response.status_code != 200:
126
+ raise FabricHTTPException(response)
127
+
128
+ responses = pagination(client, response)
129
+
130
+ for r in responses:
131
+ for v in r.get("value", []):
132
+ new_data = {
133
+ "Connection Name": v.get("displayName"),
134
+ "Connection Id": v.get("id"),
135
+ "Connectivity Type": v.get("connectivityType"),
136
+ "Connection Type": v.get("connectionDetails", {}).get("type"),
137
+ "Connection Path": v.get("connectionDetails", {}).get("path"),
138
+ "Gateway Id": v.get("gatewayId"),
139
+ }
140
+
141
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
142
+
143
+ return df
4
144
 
5
145
 
6
146
  def create_connection_cloud(
@@ -0,0 +1,156 @@
1
+ import sempy.fabric as fabric
2
+ import pandas as pd
3
+ import sempy_labs._icons as icons
4
+ from typing import Optional
5
+ from sempy_labs._helper_functions import (
6
+ resolve_workspace_name_and_id,
7
+ lro,
8
+ pagination,
9
+ )
10
+ from sempy.fabric.exceptions import FabricHTTPException
11
+
12
+
13
+ def create_environment(
14
+ environment: str, description: Optional[str] = None, workspace: Optional[str] = None
15
+ ):
16
+ """
17
+ Creates a Fabric environment.
18
+
19
+ Parameters
20
+ ----------
21
+ environment: str
22
+ Name of the environment.
23
+ description : str, default=None
24
+ A description of the environment.
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
+
31
+ (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
32
+
33
+ request_body = {"displayName": environment}
34
+
35
+ if description:
36
+ request_body["description"] = description
37
+
38
+ client = fabric.FabricRestClient()
39
+ response = client.post(
40
+ f"/v1/workspaces/{workspace_id}/environments", json=request_body
41
+ )
42
+
43
+ lro(client, response, status_codes=[201, 202])
44
+
45
+ print(
46
+ f"{icons.green_dot} The '{environment}' environment has been created within the '{workspace}' workspace."
47
+ )
48
+
49
+
50
+ def list_environments(workspace: Optional[str] = None) -> pd.DataFrame:
51
+ """
52
+ Shows the environments within a workspace.
53
+
54
+ Parameters
55
+ ----------
56
+ workspace : str, default=None
57
+ The Fabric workspace name.
58
+ Defaults to None which resolves to the workspace of the attached lakehouse
59
+ or if no lakehouse attached, resolves to the workspace of the notebook.
60
+
61
+ Returns
62
+ -------
63
+ pandas.DataFrame
64
+ A pandas dataframe showing the environments within a workspace.
65
+ """
66
+
67
+ df = pd.DataFrame(columns=["Environment Name", "Environment Id", "Description"])
68
+
69
+ (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
70
+
71
+ client = fabric.FabricRestClient()
72
+ response = client.get(f"/v1/workspaces/{workspace_id}/environments")
73
+ if response.status_code != 200:
74
+ raise FabricHTTPException(response)
75
+
76
+ responses = pagination(client, response)
77
+
78
+ for r in responses:
79
+ for v in r.get("value", []):
80
+ new_data = {
81
+ "Environment Name": v.get("displayName"),
82
+ "Environment Id": v.get("id"),
83
+ "Description": v.get("description"),
84
+ }
85
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
86
+
87
+ return df
88
+
89
+
90
+ def delete_environment(environment: str, workspace: Optional[str] = None):
91
+ """
92
+ Deletes a Fabric environment.
93
+
94
+ Parameters
95
+ ----------
96
+ environment: str
97
+ Name of the environment.
98
+ workspace : str, default=None
99
+ The Fabric workspace name.
100
+ Defaults to None which resolves to the workspace of the attached lakehouse
101
+ or if no lakehouse attached, resolves to the workspace of the notebook.
102
+ """
103
+
104
+ from sempy_labs._helper_functions import resolve_environment_id
105
+
106
+ (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
107
+ environment_id = resolve_environment_id(
108
+ environment=environment, workspace=workspace
109
+ )
110
+
111
+ client = fabric.FabricRestClient()
112
+ response = client.delete(
113
+ f"/v1/workspaces/{workspace_id}/environments/{environment_id}"
114
+ )
115
+
116
+ if response.status_code != 200:
117
+ raise FabricHTTPException(response)
118
+
119
+ print(
120
+ f"{icons.green_dot} The '{environment}' environment within the '{workspace}' workspace has been deleted."
121
+ )
122
+
123
+
124
+ def publish_environment(environment: str, workspace: Optional[str] = None):
125
+ """
126
+ Publishes a Fabric environment.
127
+
128
+ Parameters
129
+ ----------
130
+ environment: str
131
+ Name of the environment.
132
+ workspace : str, default=None
133
+ The Fabric workspace name.
134
+ Defaults to None which resolves to the workspace of the attached lakehouse
135
+ or if no lakehouse attached, resolves to the workspace of the notebook.
136
+ """
137
+
138
+ # https://learn.microsoft.com/en-us/rest/api/fabric/environment/spark-libraries/publish-environment?tabs=HTTP
139
+
140
+ from sempy_labs._helper_functions import resolve_environment_id
141
+
142
+ (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
143
+ environment_id = resolve_environment_id(
144
+ environment=environment, workspace=workspace
145
+ )
146
+
147
+ client = fabric.FabricRestClient()
148
+ response = client.post(
149
+ f"/v1/workspaces/{workspace_id}/environments/{environment_id}/staging/publish"
150
+ )
151
+
152
+ lro(client, response)
153
+
154
+ print(
155
+ f"{icons.green_dot} The '{environment}' environment within the '{workspace}' workspace has been published."
156
+ )
sempy_labs/_git.py CHANGED
@@ -132,19 +132,18 @@ def get_git_status(workspace: Optional[str] = None) -> pd.DataFrame:
132
132
  client = fabric.FabricRestClient()
133
133
  response = client.get(f"/v1/workspaces/{workspace_id}/git/status")
134
134
 
135
- if response not in [200, 202]:
135
+ if response.status_code not in [200, 202]:
136
136
  raise FabricHTTPException(response)
137
137
 
138
138
  result = lro(client, response).json()
139
139
 
140
- for v in result.get("value", []):
141
- changes = v.get("changes", [])
140
+ for changes in result.get("changes", []):
142
141
  item_metadata = changes.get("itemMetadata", {})
143
142
  item_identifier = item_metadata.get("itemIdentifier", {})
144
143
 
145
144
  new_data = {
146
- "Workspace Head": v.get("workspaceHead"),
147
- "Remote Commit Hash": v.get("remoteCommitHash"),
145
+ "Workspace Head": result.get("workspaceHead"),
146
+ "Remote Commit Hash": result.get("remoteCommitHash"),
148
147
  "Object ID": item_identifier.get("objectId"),
149
148
  "Logical ID": item_identifier.get("logicalId"),
150
149
  "Item Type": item_metadata.get("itemType"),
@@ -199,21 +198,21 @@ def get_git_connection(workspace: Optional[str] = None) -> pd.DataFrame:
199
198
  if response.status_code != 200:
200
199
  raise FabricHTTPException(response)
201
200
 
202
- for v in response.json().get("value", []):
203
- provider_details = v.get("gitProviderDetails", {})
204
- sync_details = v.get("gitSyncDetails", {})
205
- new_data = {
206
- "Organization Name": provider_details.get("organizationName"),
207
- "Project Name": provider_details.get("projectName"),
208
- "Git Provider Type": provider_details.get("gitProviderType"),
209
- "Repository Name": provider_details.get("repositoryName"),
210
- "Branch Name": provider_details.get("branchName"),
211
- "Directory Name": provider_details.get("directoryName"),
212
- "Workspace Head": sync_details.get("head"),
213
- "Last Sync Time": sync_details.get("lastSyncTime"),
214
- "Git Conneciton State": v.get("gitConnectionState"),
215
- }
216
- df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
201
+ r = response.json()
202
+ provider_details = r.get("gitProviderDetails", {})
203
+ sync_details = r.get("gitSyncDetails", {})
204
+ new_data = {
205
+ "Organization Name": provider_details.get("organizationName"),
206
+ "Project Name": provider_details.get("projectName"),
207
+ "Git Provider Type": provider_details.get("gitProviderType"),
208
+ "Repository Name": provider_details.get("repositoryName"),
209
+ "Branch Name": provider_details.get("branchName"),
210
+ "Directory Name": provider_details.get("directoryName"),
211
+ "Workspace Head": sync_details.get("head"),
212
+ "Last Sync Time": sync_details.get("lastSyncTime"),
213
+ "Git Connection State": r.get("gitConnectionState"),
214
+ }
215
+ df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
217
216
 
218
217
  return df
219
218
 
@@ -237,7 +236,7 @@ def initialize_git_connection(workspace: Optional[str] = None):
237
236
  client = fabric.FabricRestClient()
238
237
  response = client.post(f"/v1/workspaces/{workspace_id}/git/initializeConnection")
239
238
 
240
- if response not in [200, 202]:
239
+ if response.status_code not in [200, 202]:
241
240
  raise FabricHTTPException(response)
242
241
 
243
242
  lro(client, response)
@@ -2,15 +2,14 @@ import sempy.fabric as fabric
2
2
  import re
3
3
  import json
4
4
  import base64
5
+ import time
6
+ from sempy.fabric.exceptions import FabricHTTPException
5
7
  import pandas as pd
6
8
  from functools import wraps
7
9
  import datetime
8
- import time
9
- from pyspark.sql import SparkSession
10
10
  from typing import Optional, Tuple, List
11
11
  from uuid import UUID
12
12
  import sempy_labs._icons as icons
13
- from sempy.fabric.exceptions import FabricHTTPException
14
13
  import urllib.parse
15
14
  from azure.core.credentials import TokenCredential, AccessToken
16
15
 
@@ -392,6 +391,7 @@ def save_as_delta_table(
392
391
  delta_table_name: str,
393
392
  write_mode: str,
394
393
  merge_schema: Optional[bool] = False,
394
+ schema: Optional[dict] = None,
395
395
  lakehouse: Optional[str] = None,
396
396
  workspace: Optional[str] = None,
397
397
  ):
@@ -408,6 +408,8 @@ def save_as_delta_table(
408
408
  The write mode for the save operation. Options: 'append', 'overwrite'.
409
409
  merge_schema : bool, default=False
410
410
  Merges the schemas of the dataframe to the delta table.
411
+ schema : dict, default=None
412
+ A dictionary showing the schema of the columns and their data types.
411
413
  lakehouse : str, default=None
412
414
  The Fabric lakehouse used by the Direct Lake semantic model.
413
415
  Defaults to None which resolves to the lakehouse attached to the notebook.
@@ -415,13 +417,22 @@ def save_as_delta_table(
415
417
  The Fabric workspace name.
416
418
  Defaults to None which resolves to the workspace of the attached lakehouse
417
419
  or if no lakehouse attached, resolves to the workspace of the notebook.
418
-
419
- Returns
420
- -------
421
- UUID
422
- The ID of the Power BI report.
423
420
  """
424
421
 
422
+ from pyspark.sql import SparkSession
423
+ from pyspark.sql.types import (
424
+ StringType,
425
+ IntegerType,
426
+ FloatType,
427
+ DateType,
428
+ StructType,
429
+ StructField,
430
+ BooleanType,
431
+ LongType,
432
+ DoubleType,
433
+ TimestampType,
434
+ )
435
+
425
436
  if workspace is None:
426
437
  workspace_id = fabric.get_workspace_id()
427
438
  workspace = fabric.resolve_workspace_name(workspace_id)
@@ -450,9 +461,32 @@ def save_as_delta_table(
450
461
  )
451
462
 
452
463
  dataframe.columns = dataframe.columns.str.replace(" ", "_")
453
-
454
464
  spark = SparkSession.builder.getOrCreate()
455
- spark_df = spark.createDataFrame(dataframe)
465
+
466
+ type_mapping = {
467
+ "string": StringType(),
468
+ "str": StringType(),
469
+ "integer": IntegerType(),
470
+ "int": IntegerType(),
471
+ "float": FloatType(),
472
+ "date": DateType(),
473
+ "bool": BooleanType(),
474
+ "boolean": BooleanType(),
475
+ "long": LongType(),
476
+ "double": DoubleType(),
477
+ "timestamp": TimestampType(),
478
+ }
479
+
480
+ if schema is None:
481
+ spark_df = spark.createDataFrame(dataframe)
482
+ else:
483
+ schema_map = StructType(
484
+ [
485
+ StructField(column_name, type_mapping[data_type], True)
486
+ for column_name, data_type in schema.items()
487
+ ]
488
+ )
489
+ spark_df = spark.createDataFrame(dataframe, schema_map)
456
490
 
457
491
  filePath = create_abfss_path(
458
492
  lakehouse_id=lakehouse_id,
@@ -781,6 +815,37 @@ def resolve_capacity_name(capacity_id: Optional[UUID] = None) -> str:
781
815
  return dfC_filt["Display Name"].iloc[0]
782
816
 
783
817
 
818
+ def resolve_capacity_id(capacity_name: Optional[str] = None) -> UUID:
819
+ """
820
+ Obtains the capacity Id for a given capacity name.
821
+
822
+ Parameters
823
+ ----------
824
+ capacity_name : str, default=None
825
+ The capacity name.
826
+ Defaults to None which resolves to the capacity id of the workspace of the attached lakehouse
827
+ or if no lakehouse attached, resolves to the capacity name of the workspace of the notebook.
828
+
829
+ Returns
830
+ -------
831
+ UUID
832
+ The capacity Id.
833
+ """
834
+
835
+ if capacity_name is None:
836
+ return get_capacity_id()
837
+
838
+ dfC = fabric.list_capacities()
839
+ dfC_filt = dfC[dfC["Display Name"] == capacity_name]
840
+
841
+ if len(dfC_filt) == 0:
842
+ raise ValueError(
843
+ f"{icons.red_dot} The '{capacity_name}' capacity does not exist."
844
+ )
845
+
846
+ return dfC_filt["Id"].iloc[0]
847
+
848
+
784
849
  def retry(sleep_time: int, timeout_error_message: str):
785
850
  def decorator(func):
786
851
  @wraps(func)
@@ -883,6 +948,7 @@ class FabricTokenCredential(TokenCredential):
883
948
  ) -> AccessToken:
884
949
 
885
950
  from notebookutils import mssparkutils
951
+
886
952
  token = mssparkutils.credentials.getToken(scopes)
887
953
  access_token = AccessToken(token, 0)
888
954
 
@@ -910,3 +976,78 @@ def resolve_warehouse_id(warehouse: str, workspace: Optional[str]):
910
976
  )
911
977
 
912
978
  return warehouse_id
979
+
980
+
981
+ def get_language_codes(languages: str | List[str]):
982
+
983
+ if isinstance(languages, str):
984
+ languages = [languages]
985
+
986
+ for i, lang in enumerate(languages):
987
+ for k, v in icons.language_map.items():
988
+ if v == lang.capitalize():
989
+ languages[i] = k
990
+ break
991
+
992
+ return languages
993
+
994
+
995
+ def get_azure_token_credentials(
996
+ key_vault_uri: str,
997
+ key_vault_tenant_id: str,
998
+ key_vault_client_id: str,
999
+ key_vault_client_secret: str,
1000
+ ) -> Tuple[str, str, dict]:
1001
+
1002
+ from notebookutils import mssparkutils
1003
+ from azure.identity import ClientSecretCredential
1004
+
1005
+ tenant_id = mssparkutils.credentials.getSecret(key_vault_uri, key_vault_tenant_id)
1006
+ client_id = mssparkutils.credentials.getSecret(key_vault_uri, key_vault_client_id)
1007
+ client_secret = mssparkutils.credentials.getSecret(
1008
+ key_vault_uri, key_vault_client_secret
1009
+ )
1010
+
1011
+ credential = ClientSecretCredential(
1012
+ tenant_id=tenant_id, client_id=client_id, client_secret=client_secret
1013
+ )
1014
+
1015
+ token = credential.get_token("https://management.azure.com/.default").token
1016
+
1017
+ headers = {
1018
+ "Authorization": f"Bearer {token}",
1019
+ "Content-Type": "application/json",
1020
+ }
1021
+
1022
+ return token, credential, headers
1023
+
1024
+
1025
+ def convert_to_alphanumeric_lowercase(input_string):
1026
+
1027
+ cleaned_string = re.sub(r"[^a-zA-Z0-9]", "", input_string)
1028
+ cleaned_string = cleaned_string.lower()
1029
+
1030
+ return cleaned_string
1031
+
1032
+
1033
+ def resolve_environment_id(environment: str, workspace: Optional[str] = None) -> UUID:
1034
+ """
1035
+ Obtains the environment Id for a given environment.
1036
+
1037
+ Parameters
1038
+ ----------
1039
+ environment: str
1040
+ Name of the environment.
1041
+ """
1042
+ from sempy_labs._environments import list_environments
1043
+
1044
+ (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
1045
+
1046
+ dfE = list_environments(workspace=workspace)
1047
+ dfE_filt = dfE[dfE["Environment Name"] == environment]
1048
+ if len(dfE_filt) == 0:
1049
+ raise ValueError(
1050
+ f"{icons.red_dot} The '{environment}' environment does not exist within the '{workspace}' workspace."
1051
+ )
1052
+
1053
+ return dfE_filt["Environment Id"].iloc[0]
sempy_labs/_icons.py CHANGED
@@ -31,3 +31,65 @@ model_bpa_name = "ModelBPA"
31
31
  report_bpa_name = "ReportBPA"
32
32
  severity_mapping = {warning: "Warning", error: "Error", info: "Info"}
33
33
  special_characters = ['"', "/", '"', ":", "|", "<", ">", "*", "?", "'", "!"]
34
+
35
+ language_map = {
36
+ "it-IT": "Italian",
37
+ "es-ES": "Spanish",
38
+ "he-IL": "Hebrew",
39
+ "pt-PT": "Portuguese",
40
+ "zh-CN": "Chinese",
41
+ "fr-FR": "French",
42
+ "da-DK": "Danish",
43
+ "cs-CZ": "Czech",
44
+ "de-DE": "German",
45
+ "el-GR": "Greek",
46
+ "fa-IR": "Persian",
47
+ "ga-IE": "Irish",
48
+ "hi-IN": "Hindi",
49
+ "hu-HU": "Hungarian",
50
+ "is-IS": "Icelandic",
51
+ "ja-JP": "Japanese",
52
+ "nl-NL": "Dutch",
53
+ "pl-PL": "Polish",
54
+ "pt-BR": "Portuguese",
55
+ "ru-RU": "Russian",
56
+ "te-IN": "Telugu",
57
+ "ta-IN": "Tamil",
58
+ "th-TH": "Thai",
59
+ "zu-ZA": "Zulu",
60
+ "am-ET": "Amharic",
61
+ "ar-AE": "Arabic",
62
+ "sv-SE": "Swedish",
63
+ "ko-KR": "Korean",
64
+ "id-ID": "Indonesian",
65
+ "mt-MT": "Maltese",
66
+ "ro-RO": "Romanian",
67
+ "sk-SK": "Slovak",
68
+ "sl-SL": "Slovenian",
69
+ "tr-TR": "Turkish",
70
+ "uk-UA": "Ukrainian",
71
+ "bg-BG": "Bulgarian",
72
+ "ca-ES": "Catalan",
73
+ "fi-FI": "Finnish",
74
+ }
75
+ workspace_roles = ["Admin", "Member", "Viewer", "Contributor"]
76
+ principal_types = ["App", "Group", "None", "User"]
77
+ azure_api_version = "2023-11-01"
78
+ migrate_capacity_suffix = "fsku"
79
+ sku_mapping = {
80
+ "A1": "F8",
81
+ "EM1": "F8",
82
+ "A2": "F16",
83
+ "EM2": "F16",
84
+ "A3": "F32",
85
+ "EM3": "F32",
86
+ "A4": "F64",
87
+ "P1": "F64",
88
+ "A5": "F128",
89
+ "P2": "F128",
90
+ "A6": "F256",
91
+ "P3": "F256",
92
+ "A7": "F512",
93
+ "P4": "F512",
94
+ "P5": "F1024",
95
+ }