Hello Ilan Margi,
I understand you are trying to send an email with an attachment using the Microsoft Graph Python SDK, and you're seeing the ErrorRequiredPropertyMissing
error.
This usually means something is missing or incorrect in the way the attachment is set up.
In your code, you are base64-encoding the file content before assigning it to the content_bytes
field. However, the SDK expects raw bytes, not a base64 string. It handles the encoding internally.
I ran into the same error when I manually encoded the content and passed it to the attachment.
Here’s a working example that resolves this issue:
import os
from dotenv import load_dotenv
from azure.identity import ClientSecretCredential
from msgraph import GraphServiceClient
from msgraph.generated.models.message import Message
from msgraph.generated.models.item_body import ItemBody
from msgraph.generated.models.body_type import BodyType
from msgraph.generated.models.recipient import Recipient
from msgraph.generated.models.email_address import EmailAddress
from msgraph.generated.models.file_attachment import FileAttachment
from msgraph.generated.users.item.send_mail.send_mail_post_request_body import SendMailPostRequestBody
import asyncio
load_dotenv()
tenant_id = os.getenv("TENANT_ID")
client_id = os.getenv("CLIENT_ID")
client_secret = os.getenv("CLIENT_SECRET")
sender_email = os.getenv("SENDER_EMAIL")
recipient_email = os.getenv("RECIPIENT_EMAIL")
attachment_path = "example.txt"
def get_graph_client():
credential = ClientSecretCredential(
tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret
)
return GraphServiceClient(credential, scopes=["https://graph.microsoft.com/.default"])
async def send_email():
try:
graph_client = get_graph_client()
with open(attachment_path, "rb") as file:
file_content = file.read()
file_attachment = FileAttachment(
odata_type="#microsoft.graph.fileAttachment",
name=os.path.basename(attachment_path),
content_type="text/plain",
content_bytes=file_content
)
message = Message(
subject="Graph SDK Email Test",
body=ItemBody(
content_type=BodyType.Text,
content="This is a test email with a .txt attachment."
),
to_recipients=[
Recipient(
email_address=EmailAddress(address=recipient_email)
)
],
attachments=[file_attachment]
)
request_body = SendMailPostRequestBody(
message=message,
save_to_sent_items=True
)
await graph_client.users.by_user_id(sender_email).send_mail.post(request_body)
print("Email sent successfully.")
except Exception as e:
print("Failed to send email.")
print(f"Error: {e}")
if __name__ == "__main__":
asyncio.run(send_email())
Response:
The email was successfully delivered with the attachment. I also verified this by checking the Sent Items
folder of the sender.
This version uses raw bytes instead of base64, which fixes the issue.
Let me know if you have any other questions or need any further assistance.
Hope this clarifies things a bit!
If this answers your query, do click Accept Answer
and Yes
for was this answer helpful, which may help members with similar questions.
If you have any other questions or are still experiencing issues, feel free to ask in the "comments" section, and I'd be happy to help.