Possible send_email enhancement #520
Replies: 8 comments 14 replies
-
|
Nice. Yeah I kept it relatively simple for now. Not sure how fancy folks want to get with this. It’s good to hear feedback like this. |
Beta Was this translation helpful? Give feedback.
-
|
Yes, makes total sense. I’ll add this in, thank you! |
Beta Was this translation helpful? Give feedback.
-
|
Would you try this? The attachments parameter is a string or list of strings of abfss_paths of the attachments (based on items in a lakehouse in Fabric). import pandas as pd
from uuid import UUID
import sempy_labs._icons as icons
from typing import List
from sempy_labs._helper_functions import (
_is_valid_uuid,
_base_api,
_create_dataframe,
)
def send_mail(
user: UUID | str,
subject: str,
to_recipients: str | List[str],
content: str,
content_type: str = "Text",
cc_recipients: str | List[str] = None,
bcc_recipients: str | List[str] = None,
priority: str = "Normal",
follow_up_flag: bool = False,
attachments: str | List[str] = None,
):
"""
Sends an email to the specified recipients.
This is a wrapper function for the following API: `user: sendMail <https://learn.microsoft.com/graph/api/user-sendmail>`_.
Service Principal Authentication is required (see `here <https://github.com/microsoft/semantic-link-labs/blob/main/notebooks/Service%20Principal.ipynb>`_ for examples).
Parameters
----------
user : uuid.UUID | str
The user ID or user principal name.
subject : str
The email subject.
to_recipients : str | List[str]
The email address of the recipients.
content : str
The email content.
content_type : str, default="Text"
The email content type. Options: "Text" or "HTML".
cc_recipients : str | List[str], default=None
The email address of the CC recipients.
bcc_recipients : str | List[str], default=None
The email address of the BCC recipients.
priority : str, default="Normal"
The email priority. Options: "Normal", "High", or "Low".
follow_up_flag : bool, default=False
Whether to set a follow-up flag for the email.
attachments : str | List[str], default=None
The abfss path or a list of the abfss paths of the attachments to include in the email.
"""
import base64
from sempy_labs._helper_functions import _create_spark_session
if content_type.lower() == "html":
content_type = "HTML"
else:
content_type = "Text"
priority = priority.capitalize()
if priority not in ["Normal", "High", "Low"]:
raise ValueError(
f"Invalid priority: {priority}. Options are: Normal, High, Low."
)
user_id = resolve_user_id(user=user)
if isinstance(to_recipients, str):
to_recipients = [to_recipients]
if isinstance(cc_recipients, str):
cc_recipients = [cc_recipients]
to_email_addresses = [
{"emailAddress": {"address": email}} for email in to_recipients
]
cc_email_addresses = (
[{"emailAddress": {"address": email}} for email in cc_recipients]
if cc_recipients
else None
)
bcc_email_addresses = (
[{"emailAddress": {"address": email}} for email in bcc_recipients]
if bcc_recipients
else None
)
payload = {
"message": {
"subject": subject,
"body": {
"contentType": content_type,
"content": content,
},
"toRecipients": to_email_addresses,
"importance": priority,
},
}
if cc_email_addresses:
payload["message"]["ccRecipients"] = cc_email_addresses
if bcc_email_addresses:
payload["message"]["bccRecipients"] = bcc_email_addresses
if follow_up_flag:
payload["message"]["flag"] = {"flagStatus": "flagged"}
if attachments:
if isinstance(attachments, str):
attachments = [attachments]
for abfss_path in attachments:
file_name = abfss_path.split("/")[-1]
if "attachments" not in payload["message"]:
payload["message"]["attachments"] = []
spark = _create_spark_session()
spark_file = (
spark.read.format("binaryFile")
.load(abfss_path)
.select("content")
.collect()[0][0]
)
content_bytes = base64.b64encode(spark_file).decode(
"utf-8"
) # Convert bytearray to base64 string
payload["message"]["attachments"].append(
{
"@odata.type": "#microsoft.graph.fileAttachment",
"name": file_name,
"contentBytes": content_bytes,
}
)
_base_api(
request=f"users/{user_id}/sendMail",
client="graph",
status_codes=202,
payload=payload,
method="post",
)
print(f"{icons.green_dot} The email has been sent to {to_recipients}.") |
Beta Was this translation helpful? Give feedback.
-
|
https://github.com/microsoft/semantic-link-labs/blob/main/src/sempy_labs/graph/_users.py |
Beta Was this translation helpful? Give feedback.
-
|
@OldDogNewTricks000 here is the branch with the updated function for testing: https://github.com/m-kovalsky/semantic-link-labs/blob/a0f05f7ce631d152aff808963bd95a660a3b10de/src/sempy_labs/graph/_users.py#L126 |
Beta Was this translation helpful? Give feedback.
-
|
You have to use the service principal authentication context manager as such: https://github.com/microsoft/semantic-link-labs/wiki/Code-Examples#send-an-email |
Beta Was this translation helpful? Give feedback.
-
|
@OldDogNewTricks000 were you able to test this using the service_principal_authentication context manager? |
Beta Was this translation helpful? Give feedback.
-
|
Thank you for updating the function. I tested about 12 different email variations and everything seems to work as expected. I'm just curious though, I tried to email myself a .geojson file from Fabric that I was using as a reference layer and it says that it is not supported. Wouldn't that be handled just like a regular .txt or .csv file? I am not sure if you are aware, but I removed follow_up_flag parameter from my function because it only flags the sending email; not the receiving email. I would suggest if you leave that in you add that clarification in the documentation. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I just noticed that in 0.9.4 you released a send_email function. I recently wrote my own, I figured I would share here in the case you want to expand on the functionality of your existing wrapper function. It would add the following options:
Beta Was this translation helpful? Give feedback.
All reactions