semantic-link-labs 0.11.0__py3-none-any.whl → 0.11.2__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.11.0.dist-info → semantic_link_labs-0.11.2.dist-info}/METADATA +6 -4
- semantic_link_labs-0.11.2.dist-info/RECORD +210 -0
- sempy_labs/__init__.py +56 -56
- sempy_labs/_a_lib_info.py +1 -1
- sempy_labs/_ai.py +1 -1
- sempy_labs/_capacities.py +2 -2
- sempy_labs/_capacity_migration.py +5 -5
- sempy_labs/_clear_cache.py +1 -1
- sempy_labs/_connections.py +2 -2
- sempy_labs/_dashboards.py +16 -16
- sempy_labs/_data_pipelines.py +1 -1
- sempy_labs/_dataflows.py +101 -26
- sempy_labs/_dax.py +3 -3
- sempy_labs/_dax_query_view.py +1 -1
- sempy_labs/_delta_analyzer.py +4 -4
- sempy_labs/_delta_analyzer_history.py +1 -1
- sempy_labs/_deployment_pipelines.py +1 -1
- sempy_labs/_environments.py +22 -21
- sempy_labs/_eventhouses.py +12 -11
- sempy_labs/_eventstreams.py +12 -11
- sempy_labs/_external_data_shares.py +23 -22
- sempy_labs/_gateways.py +47 -45
- sempy_labs/_generate_semantic_model.py +3 -3
- sempy_labs/_git.py +1 -1
- sempy_labs/_graphQL.py +12 -11
- sempy_labs/_job_scheduler.py +56 -54
- sempy_labs/_kql_databases.py +16 -17
- sempy_labs/_kql_querysets.py +12 -11
- sempy_labs/_kusto.py +2 -2
- sempy_labs/_list_functions.py +1 -1
- sempy_labs/_managed_private_endpoints.py +18 -15
- sempy_labs/_mirrored_databases.py +16 -15
- sempy_labs/_mirrored_warehouses.py +12 -11
- sempy_labs/_ml_experiments.py +11 -10
- sempy_labs/_ml_models.py +11 -10
- sempy_labs/_model_auto_build.py +3 -3
- sempy_labs/_model_bpa.py +5 -5
- sempy_labs/_model_bpa_bulk.py +3 -3
- sempy_labs/_model_dependencies.py +1 -1
- sempy_labs/_mounted_data_factories.py +12 -12
- sempy_labs/_notebooks.py +1 -1
- sempy_labs/_one_lake_integration.py +1 -1
- sempy_labs/_query_scale_out.py +1 -1
- sempy_labs/_refresh_semantic_model.py +1 -1
- sempy_labs/_semantic_models.py +30 -28
- sempy_labs/_spark.py +1 -1
- sempy_labs/_sql.py +1 -1
- sempy_labs/_sql_endpoints.py +12 -11
- sempy_labs/_sqldatabase.py +15 -15
- sempy_labs/_tags.py +11 -10
- sempy_labs/_translations.py +1 -1
- sempy_labs/_user_delegation_key.py +2 -2
- sempy_labs/_variable_libraries.py +13 -12
- sempy_labs/_vertipaq.py +3 -3
- sempy_labs/_vpax.py +1 -1
- sempy_labs/_warehouses.py +15 -14
- sempy_labs/_workloads.py +1 -1
- sempy_labs/_workspace_identity.py +1 -1
- sempy_labs/_workspaces.py +14 -13
- sempy_labs/admin/__init__.py +18 -18
- sempy_labs/admin/_activities.py +46 -46
- sempy_labs/admin/_apps.py +28 -26
- sempy_labs/admin/_artifacts.py +15 -15
- sempy_labs/admin/_basic_functions.py +1 -2
- sempy_labs/admin/_capacities.py +86 -82
- sempy_labs/admin/_dataflows.py +2 -2
- sempy_labs/admin/_datasets.py +50 -48
- sempy_labs/admin/_domains.py +25 -19
- sempy_labs/admin/_external_data_share.py +24 -22
- sempy_labs/admin/_git.py +17 -17
- sempy_labs/admin/_items.py +47 -45
- sempy_labs/admin/_reports.py +61 -58
- sempy_labs/admin/_scanner.py +2 -2
- sempy_labs/admin/_shared.py +18 -18
- sempy_labs/admin/_tags.py +2 -2
- sempy_labs/admin/_tenant.py +57 -51
- sempy_labs/admin/_users.py +16 -15
- sempy_labs/admin/_workspaces.py +2 -2
- sempy_labs/directlake/__init__.py +12 -12
- sempy_labs/directlake/_directlake_schema_compare.py +3 -3
- sempy_labs/directlake/_directlake_schema_sync.py +9 -7
- sempy_labs/directlake/_dl_helper.py +1 -1
- sempy_labs/directlake/_generate_shared_expression.py +1 -1
- sempy_labs/directlake/_get_directlake_lakehouse.py +1 -1
- sempy_labs/directlake/_guardrails.py +1 -1
- sempy_labs/directlake/_list_directlake_model_calc_tables.py +3 -3
- sempy_labs/directlake/_show_unsupported_directlake_objects.py +1 -1
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +3 -3
- sempy_labs/directlake/_update_directlake_partition_entity.py +4 -4
- sempy_labs/directlake/_warm_cache.py +3 -3
- sempy_labs/graph/__init__.py +3 -3
- sempy_labs/graph/_groups.py +81 -78
- sempy_labs/graph/_teams.py +21 -21
- sempy_labs/graph/_users.py +111 -10
- sempy_labs/lakehouse/__init__.py +7 -7
- sempy_labs/lakehouse/_blobs.py +30 -30
- sempy_labs/lakehouse/_get_lakehouse_columns.py +2 -2
- sempy_labs/lakehouse/_get_lakehouse_tables.py +29 -27
- sempy_labs/lakehouse/_helper.py +30 -2
- sempy_labs/lakehouse/_lakehouse.py +2 -2
- sempy_labs/lakehouse/_livy_sessions.py +47 -42
- sempy_labs/lakehouse/_shortcuts.py +22 -21
- sempy_labs/migration/__init__.py +8 -8
- sempy_labs/migration/_create_pqt_file.py +2 -2
- sempy_labs/migration/_migrate_calctables_to_lakehouse.py +3 -3
- sempy_labs/migration/_migrate_calctables_to_semantic_model.py +3 -4
- sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +2 -2
- sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +4 -4
- sempy_labs/migration/_migration_validation.py +1 -2
- sempy_labs/migration/_refresh_calc_tables.py +2 -2
- sempy_labs/mirrored_azure_databricks_catalog/__init__.py +2 -2
- sempy_labs/mirrored_azure_databricks_catalog/_discover.py +40 -40
- sempy_labs/mirrored_azure_databricks_catalog/_refresh_catalog_metadata.py +1 -1
- sempy_labs/report/__init__.py +10 -10
- sempy_labs/report/_download_report.py +2 -2
- sempy_labs/report/_export_report.py +2 -2
- sempy_labs/report/_generate_report.py +1 -1
- sempy_labs/report/_paginated.py +1 -1
- sempy_labs/report/_report_bpa.py +4 -3
- sempy_labs/report/_report_functions.py +3 -3
- sempy_labs/report/_report_list_functions.py +3 -3
- sempy_labs/report/_report_rebind.py +1 -1
- sempy_labs/report/_reportwrapper.py +247 -249
- sempy_labs/report/_save_report.py +3 -3
- sempy_labs/theme/_org_themes.py +35 -1
- sempy_labs/tom/__init__.py +1 -1
- sempy_labs/tom/_model.py +23 -20
- semantic_link_labs-0.11.0.dist-info/RECORD +0 -210
- {semantic_link_labs-0.11.0.dist-info → semantic_link_labs-0.11.2.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.11.0.dist-info → semantic_link_labs-0.11.2.dist-info}/licenses/LICENSE +0 -0
- {semantic_link_labs-0.11.0.dist-info → semantic_link_labs-0.11.2.dist-info}/top_level.txt +0 -0
sempy_labs/graph/_groups.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
from uuid import UUID
|
|
3
|
-
from
|
|
3
|
+
from .._helper_functions import (
|
|
4
4
|
_is_valid_uuid,
|
|
5
5
|
_base_api,
|
|
6
6
|
_create_dataframe,
|
|
@@ -75,27 +75,28 @@ def list_groups() -> pd.DataFrame:
|
|
|
75
75
|
|
|
76
76
|
df = _create_dataframe(columns=columns)
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
rows = []
|
|
79
79
|
for v in result.get("value"):
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
80
|
+
rows.append(
|
|
81
|
+
{
|
|
82
|
+
"Group Id": v.get("id"),
|
|
83
|
+
"Group Name": v.get("displayName"),
|
|
84
|
+
"Mail": v.get("mail"),
|
|
85
|
+
"Description": v.get("description"),
|
|
86
|
+
"Classification": v.get("classification"),
|
|
87
|
+
"Mail Enabled": v.get("mailEnabled"),
|
|
88
|
+
"Security Enabled": v.get("securityEnabled"),
|
|
89
|
+
"Created Date Time": v.get("createdDateTime"),
|
|
90
|
+
"Expiration Date Time": v.get("expirationDateTime"),
|
|
91
|
+
"Renewed Date Time": v.get("renewedDateTime"),
|
|
92
|
+
"Deleted Date Time": v.get("deletedDateTime"),
|
|
93
|
+
"Visibility": v.get("visibility"),
|
|
94
|
+
"Security Identifier": v.get("securityIdentifier"),
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
if rows:
|
|
99
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
99
100
|
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
100
101
|
|
|
101
102
|
return df
|
|
@@ -140,28 +141,28 @@ def _get_group(group_id: UUID) -> pd.DataFrame:
|
|
|
140
141
|
}
|
|
141
142
|
df = _create_dataframe(columns=columns)
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
rows = []
|
|
144
145
|
for v in result.get("value"):
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if
|
|
164
|
-
df = pd.
|
|
146
|
+
rows.append(
|
|
147
|
+
{
|
|
148
|
+
"Group Id": v.get("id"),
|
|
149
|
+
"Group Name": v.get("displayName"),
|
|
150
|
+
"Mail": v.get("mail"),
|
|
151
|
+
"Description": v.get("description"),
|
|
152
|
+
"Classification": v.get("classification"),
|
|
153
|
+
"Mail Enabled": v.get("mailEnabled"),
|
|
154
|
+
"Security Enabled": v.get("securityEnabled"),
|
|
155
|
+
"Created Date Time": v.get("createdDateTime"),
|
|
156
|
+
"Expiration Date Time": v.get("expirationDateTime"),
|
|
157
|
+
"Deleted Date Time": v.get("deletedDateTime"),
|
|
158
|
+
"Renewed Date Time": v.get("renewedDateTime"),
|
|
159
|
+
"Visibility": v.get("visibility"),
|
|
160
|
+
"Security Identifier": v.get("securityIdentifier"),
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
if rows:
|
|
165
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
165
166
|
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
166
167
|
|
|
167
168
|
return df
|
|
@@ -207,25 +208,26 @@ def list_group_members(group: str | UUID) -> pd.DataFrame:
|
|
|
207
208
|
|
|
208
209
|
df = _create_dataframe(columns=columns)
|
|
209
210
|
|
|
210
|
-
|
|
211
|
+
rows = []
|
|
211
212
|
for v in result.get("value"):
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
213
|
+
rows.append(
|
|
214
|
+
{
|
|
215
|
+
"Member Id": v.get("id"),
|
|
216
|
+
"Member Name": v.get("displayName"),
|
|
217
|
+
"User Principal Name": v.get("userPrincipalName"),
|
|
218
|
+
"Mail": v.get("mail"),
|
|
219
|
+
"Job Title": v.get("jobTitle"),
|
|
220
|
+
"Office Location": v.get("officeLocation"),
|
|
221
|
+
"Mobile Phone": v.get("mobilePhone"),
|
|
222
|
+
"Business Phones": str(v.get("businessPhones")),
|
|
223
|
+
"Preferred Language": v.get("preferredLanguage"),
|
|
224
|
+
"Given Name": v.get("givenName"),
|
|
225
|
+
"Surname": v.get("surname"),
|
|
226
|
+
}
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
if rows:
|
|
230
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
229
231
|
|
|
230
232
|
return df
|
|
231
233
|
|
|
@@ -270,25 +272,26 @@ def list_group_owners(group: str | UUID) -> pd.DataFrame:
|
|
|
270
272
|
|
|
271
273
|
df = _create_dataframe(columns=columns)
|
|
272
274
|
|
|
273
|
-
|
|
275
|
+
rows = []
|
|
274
276
|
for v in result.get("value"):
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
277
|
+
rows.append(
|
|
278
|
+
{
|
|
279
|
+
"Owner Id": v.get("id"),
|
|
280
|
+
"Owner Name": v.get("displayName"),
|
|
281
|
+
"User Principal Name": v.get("userPrincipalName"),
|
|
282
|
+
"Mail": v.get("mail"),
|
|
283
|
+
"Job Title": v.get("jobTitle"),
|
|
284
|
+
"Office Location": v.get("officeLocation"),
|
|
285
|
+
"Mobile Phone": v.get("mobilePhone"),
|
|
286
|
+
"Business Phones": str(v.get("businessPhones")),
|
|
287
|
+
"Preferred Language": v.get("preferredLanguage"),
|
|
288
|
+
"Given Name": v.get("givenName"),
|
|
289
|
+
"Surname": v.get("surname"),
|
|
290
|
+
}
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
if rows:
|
|
294
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
292
295
|
|
|
293
296
|
return df
|
|
294
297
|
|
sempy_labs/graph/_teams.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
from uuid import UUID
|
|
3
3
|
from sempy._utils._log import log
|
|
4
|
-
from
|
|
4
|
+
from .._helper_functions import (
|
|
5
5
|
_base_api,
|
|
6
6
|
_create_dataframe,
|
|
7
7
|
_update_dataframe_datatypes,
|
|
@@ -42,27 +42,27 @@ def list_teams() -> pd.DataFrame:
|
|
|
42
42
|
|
|
43
43
|
df = _create_dataframe(columns=columns)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
rows = []
|
|
46
46
|
for v in result.get("value"):
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if
|
|
65
|
-
df = pd.
|
|
47
|
+
rows.append(
|
|
48
|
+
{
|
|
49
|
+
"Team Id": v.get("id"),
|
|
50
|
+
"Team Name": v.get("displayName"),
|
|
51
|
+
"Description": v.get("description"),
|
|
52
|
+
"Creation Date Time": v.get("createdDateTime"),
|
|
53
|
+
"Classification": v.get("classification"),
|
|
54
|
+
"Specialization": v.get("specialization"),
|
|
55
|
+
"Visibility": v.get("visibility"),
|
|
56
|
+
"Web Url": v.get("webUrl"),
|
|
57
|
+
"Archived": v.get("isArchived"),
|
|
58
|
+
"Favorite By Me": v.get("isFavoriteByMe"),
|
|
59
|
+
"Discoverable By Me": v.get("isDiscoverableByMe"),
|
|
60
|
+
"Member Count": v.get("memberCount"),
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
if rows:
|
|
65
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
66
66
|
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
67
67
|
|
|
68
68
|
return df
|
sempy_labs/graph/_users.py
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
|
+
import os
|
|
3
|
+
import base64
|
|
2
4
|
from uuid import UUID
|
|
3
5
|
import sempy_labs._icons as icons
|
|
4
|
-
from typing import List
|
|
5
|
-
from
|
|
6
|
+
from typing import List, Literal, Optional
|
|
7
|
+
from .._helper_functions import (
|
|
6
8
|
_is_valid_uuid,
|
|
7
9
|
_base_api,
|
|
8
10
|
_create_dataframe,
|
|
11
|
+
_mount,
|
|
9
12
|
)
|
|
10
13
|
from sempy._utils._log import log
|
|
11
14
|
|
|
@@ -130,8 +133,12 @@ def send_mail(
|
|
|
130
133
|
subject: str,
|
|
131
134
|
to_recipients: str | List[str],
|
|
132
135
|
content: str,
|
|
133
|
-
content_type:
|
|
134
|
-
cc_recipients: str | List[str] = None,
|
|
136
|
+
content_type: Literal["Text", "HTML"] = "Text",
|
|
137
|
+
cc_recipients: Optional[str | List[str]] = None,
|
|
138
|
+
bcc_recipients: Optional[str | List[str]] = None,
|
|
139
|
+
priority: Literal["Normal", "High", "Low"] = "Normal",
|
|
140
|
+
follow_up_flag: bool = False,
|
|
141
|
+
attachments: Optional[str | List[str]] = None,
|
|
135
142
|
):
|
|
136
143
|
"""
|
|
137
144
|
Sends an email to the specified recipients.
|
|
@@ -150,16 +157,27 @@ def send_mail(
|
|
|
150
157
|
The email address of the recipients.
|
|
151
158
|
content : str
|
|
152
159
|
The email content.
|
|
153
|
-
content_type :
|
|
160
|
+
content_type : Literal["Text", "HTML"], default="Text"
|
|
154
161
|
The email content type. Options: "Text" or "HTML".
|
|
155
162
|
cc_recipients : str | List[str], default=None
|
|
156
163
|
The email address of the CC recipients.
|
|
164
|
+
bcc_recipients : str | List[str], default=None
|
|
165
|
+
The email address of the BCC recipients.
|
|
166
|
+
priority : Literal["Normal", "High", "Low"], default="Normal"
|
|
167
|
+
The email priority.
|
|
168
|
+
follow_up_flag : bool, default=False
|
|
169
|
+
Whether to set a follow-up flag for the email.
|
|
170
|
+
attachments : str | List[str], default=None
|
|
171
|
+
The abfss path or a list of the abfss paths of the attachments to include in the email.
|
|
157
172
|
"""
|
|
158
173
|
|
|
159
|
-
if content_type.lower() == "html"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
174
|
+
content_type = "HTML" if content_type.lower() == "html" else "Text"
|
|
175
|
+
|
|
176
|
+
priority = priority.capitalize()
|
|
177
|
+
if priority not in ["Normal", "High", "Low"]:
|
|
178
|
+
raise ValueError(
|
|
179
|
+
f"{icons.red_dot} Invalid priority: {priority}. Options are: Normal, High, Low."
|
|
180
|
+
)
|
|
163
181
|
|
|
164
182
|
user_id = resolve_user_id(user=user)
|
|
165
183
|
|
|
@@ -178,6 +196,11 @@ def send_mail(
|
|
|
178
196
|
if cc_recipients
|
|
179
197
|
else None
|
|
180
198
|
)
|
|
199
|
+
bcc_email_addresses = (
|
|
200
|
+
[{"emailAddress": {"address": email}} for email in bcc_recipients]
|
|
201
|
+
if bcc_recipients
|
|
202
|
+
else None
|
|
203
|
+
)
|
|
181
204
|
|
|
182
205
|
payload = {
|
|
183
206
|
"message": {
|
|
@@ -187,12 +210,83 @@ def send_mail(
|
|
|
187
210
|
"content": content,
|
|
188
211
|
},
|
|
189
212
|
"toRecipients": to_email_addresses,
|
|
213
|
+
"importance": priority,
|
|
190
214
|
},
|
|
191
215
|
}
|
|
192
216
|
|
|
193
217
|
if cc_email_addresses:
|
|
194
218
|
payload["message"]["ccRecipients"] = cc_email_addresses
|
|
195
219
|
|
|
220
|
+
if bcc_email_addresses:
|
|
221
|
+
payload["message"]["bccRecipients"] = bcc_email_addresses
|
|
222
|
+
|
|
223
|
+
if follow_up_flag:
|
|
224
|
+
payload["message"]["flag"] = {"flagStatus": "flagged"}
|
|
225
|
+
|
|
226
|
+
content_types = {
|
|
227
|
+
".txt": "text/plain",
|
|
228
|
+
".pdf": "application/pdf",
|
|
229
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
230
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
231
|
+
".csv": "text/csv",
|
|
232
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
233
|
+
".jpg": "image/jpeg",
|
|
234
|
+
".jpeg": "image/jpeg",
|
|
235
|
+
".png": "image/png",
|
|
236
|
+
".gif": "image/gif",
|
|
237
|
+
".bmp": "image/bmp",
|
|
238
|
+
".zip": "application/zip",
|
|
239
|
+
".json": "application/json",
|
|
240
|
+
".xml": "application/xml",
|
|
241
|
+
".html": "text/html",
|
|
242
|
+
".bim": "application/json",
|
|
243
|
+
".pbix": "application/vnd.ms-powerbi.report",
|
|
244
|
+
".pbip": "application/vnd.ms-powerbi.report",
|
|
245
|
+
".pbit": "application/vnd.ms-powerbi.report",
|
|
246
|
+
".vpax": "application/zip",
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
def file_path_to_content_bytes(file_path):
|
|
250
|
+
|
|
251
|
+
path_parts = file_path.split("abfss://")[1].split("@")
|
|
252
|
+
workspace = path_parts[0]
|
|
253
|
+
|
|
254
|
+
rest = path_parts[1].split(".microsoft.com/")[1]
|
|
255
|
+
lakehouse, *file_parts = rest.split("/")
|
|
256
|
+
if lakehouse.endswith(".Lakehouse"):
|
|
257
|
+
lakehouse = lakehouse.removesuffix(".Lakehouse")
|
|
258
|
+
relative_path = os.path.join(*file_parts)
|
|
259
|
+
|
|
260
|
+
local_path = _mount(lakehouse, workspace)
|
|
261
|
+
full_path = os.path.join(local_path, relative_path)
|
|
262
|
+
|
|
263
|
+
with open(full_path, "rb") as file:
|
|
264
|
+
return base64.b64encode(file.read()).decode("utf-8")
|
|
265
|
+
|
|
266
|
+
if isinstance(attachments, str):
|
|
267
|
+
attachments = [attachments]
|
|
268
|
+
if attachments:
|
|
269
|
+
attachments_list = []
|
|
270
|
+
for attach_path in attachments:
|
|
271
|
+
content_bytes = file_path_to_content_bytes(attach_path)
|
|
272
|
+
file_extension = os.path.splitext(attach_path)[1]
|
|
273
|
+
content_type = content_types.get(file_extension)
|
|
274
|
+
if not content_type:
|
|
275
|
+
raise ValueError(
|
|
276
|
+
f"{icons.red_dot} Unsupported file type: {file_extension}. Supported types are: {', '.join(content_types.keys())}."
|
|
277
|
+
)
|
|
278
|
+
attachments_list.append(
|
|
279
|
+
{
|
|
280
|
+
"@odata.type": "#microsoft.graph.fileAttachment",
|
|
281
|
+
"name": attach_path.split("/")[-1],
|
|
282
|
+
"contentType": content_type,
|
|
283
|
+
"contentBytes": content_bytes,
|
|
284
|
+
}
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
# Add to payload
|
|
288
|
+
payload["message"]["attachments"] = attachments_list
|
|
289
|
+
|
|
196
290
|
_base_api(
|
|
197
291
|
request=f"users/{user_id}/sendMail",
|
|
198
292
|
client="graph",
|
|
@@ -201,4 +295,11 @@ def send_mail(
|
|
|
201
295
|
method="post",
|
|
202
296
|
)
|
|
203
297
|
|
|
204
|
-
|
|
298
|
+
printout = f"{icons.green_dot} The email has been sent to {to_recipients}"
|
|
299
|
+
if cc_recipients:
|
|
300
|
+
printout += f" and CCed to {cc_recipients}"
|
|
301
|
+
if bcc_recipients:
|
|
302
|
+
printout += f" and BCCed to {bcc_recipients}"
|
|
303
|
+
if attachments:
|
|
304
|
+
printout += f" with {len(attachments)} attachment(s)"
|
|
305
|
+
print(f"{printout}.")
|
sempy_labs/lakehouse/__init__.py
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
from
|
|
1
|
+
from ._get_lakehouse_columns import (
|
|
2
2
|
get_lakehouse_columns,
|
|
3
3
|
)
|
|
4
|
-
from
|
|
4
|
+
from ._get_lakehouse_tables import (
|
|
5
5
|
get_lakehouse_tables,
|
|
6
6
|
)
|
|
7
|
-
from
|
|
7
|
+
from ._lakehouse import (
|
|
8
8
|
lakehouse_attached,
|
|
9
9
|
optimize_lakehouse_tables,
|
|
10
10
|
vacuum_lakehouse_tables,
|
|
11
11
|
run_table_maintenance,
|
|
12
12
|
)
|
|
13
|
-
from
|
|
13
|
+
from ._shortcuts import (
|
|
14
14
|
# create_shortcut,
|
|
15
15
|
create_shortcut_onelake,
|
|
16
16
|
delete_shortcut,
|
|
17
17
|
reset_shortcut_cache,
|
|
18
18
|
list_shortcuts,
|
|
19
19
|
)
|
|
20
|
-
from
|
|
20
|
+
from ._blobs import (
|
|
21
21
|
recover_lakehouse_object,
|
|
22
22
|
list_blobs,
|
|
23
23
|
)
|
|
24
|
-
from
|
|
24
|
+
from ._livy_sessions import (
|
|
25
25
|
list_livy_sessions,
|
|
26
26
|
)
|
|
27
|
-
from
|
|
27
|
+
from ._helper import (
|
|
28
28
|
is_v_ordered,
|
|
29
29
|
delete_lakehouse,
|
|
30
30
|
update_lakehouse,
|
sempy_labs/lakehouse/_blobs.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from .._helper_functions import (
|
|
2
2
|
resolve_workspace_id,
|
|
3
3
|
resolve_lakehouse_id,
|
|
4
4
|
_xml_to_dict,
|
|
@@ -146,7 +146,7 @@ def list_blobs(
|
|
|
146
146
|
uses_pagination=True,
|
|
147
147
|
)
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
rows = []
|
|
150
150
|
for root in responses:
|
|
151
151
|
response_json = _xml_to_dict(root)
|
|
152
152
|
|
|
@@ -159,34 +159,34 @@ def list_blobs(
|
|
|
159
159
|
|
|
160
160
|
for blob in blobs:
|
|
161
161
|
p = blob.get("Properties", {})
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if
|
|
189
|
-
df = pd.
|
|
162
|
+
rows.append(
|
|
163
|
+
{
|
|
164
|
+
"Blob Name": blob.get("Name"),
|
|
165
|
+
"Is Deleted": blob.get("Deleted", False),
|
|
166
|
+
"Deletion Id": blob.get("DeletionId"),
|
|
167
|
+
"Creation Time": p.get("Creation-Time"),
|
|
168
|
+
"Expiry Time": p.get("Expiry-Time"),
|
|
169
|
+
"Etag": p.get("Etag"),
|
|
170
|
+
"Resource Type": p.get("ResourceType"),
|
|
171
|
+
"Content Length": p.get("Content-Length"),
|
|
172
|
+
"Content Type": p.get("Content-Type"),
|
|
173
|
+
"Content Encoding": p.get("Content-Encoding"),
|
|
174
|
+
"Content Language": p.get("Content-Language"),
|
|
175
|
+
"Content CRC64": p.get("Content-CRC64"),
|
|
176
|
+
"Content MD5": p.get("Content-MD5"),
|
|
177
|
+
"Cache Control": p.get("Cache-Control"),
|
|
178
|
+
"Content Disposition": p.get("Content-Disposition"),
|
|
179
|
+
"Blob Type": p.get("BlobType"),
|
|
180
|
+
"Access Tier": p.get("AccessTier"),
|
|
181
|
+
"Access Tier Inferred": p.get("AccessTierInferred"),
|
|
182
|
+
"Server Encrypted": p.get("ServerEncrypted"),
|
|
183
|
+
"Deleted Time": p.get("DeletedTime"),
|
|
184
|
+
"Remaining Retention Days": p.get("RemainingRetentionDays"),
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
if rows:
|
|
189
|
+
df = pd.DataFrame(rows, columns=list(columns.keys()))
|
|
190
190
|
_update_dataframe_datatypes(dataframe=df, column_map=columns)
|
|
191
191
|
|
|
192
192
|
return df
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
import re
|
|
3
|
-
from
|
|
3
|
+
from .._helper_functions import (
|
|
4
4
|
format_dax_object_name,
|
|
5
5
|
resolve_workspace_name_and_id,
|
|
6
6
|
resolve_lakehouse_name_and_id,
|
|
@@ -38,7 +38,7 @@ def get_lakehouse_columns(
|
|
|
38
38
|
pandas.DataFrame
|
|
39
39
|
Shows the tables/columns within a lakehouse and their properties.
|
|
40
40
|
"""
|
|
41
|
-
from
|
|
41
|
+
from ._get_lakehouse_tables import get_lakehouse_tables
|
|
42
42
|
|
|
43
43
|
columns = {
|
|
44
44
|
"Workspace Name": "string",
|