O365 - Microsoft Graph and Office 365 API made easy
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Complete email management including inbox access, message composition, folder operations, attachment handling, and search capabilities with support for shared mailboxes.
Access mailboxes for the authenticated user or other users (with proper permissions).
def mailbox(self, resource: str = None) -> MailBox:
"""
Get a mailbox instance.
Parameters:
- resource: user resource identifier (defaults to authenticated user)
Returns:
- MailBox: Mailbox instance for email operations
"""
class MailBox:
def __init__(self, parent: Account, main_resource: str = None): ...
# Well-known folder shortcuts
def inbox_folder(self) -> Folder:
"""Get the inbox folder."""
def sent_folder(self) -> Folder:
"""Get the sent items folder."""
def drafts_folder(self) -> Folder:
"""Get the drafts folder."""
def deleted_folder(self) -> Folder:
"""Get the deleted items folder."""
def junk_folder(self) -> Folder:
"""Get the junk email folder."""
def outbox_folder(self) -> Folder:
"""Get the outbox folder."""
def archive_folder(self) -> Folder:
"""Get the archive folder."""
def clutter_folder(self) -> Folder:
"""Get the clutter folder."""
def conflicts_folder(self) -> Folder:
"""Get the conflicts folder."""
def conversationhistory_folder(self) -> Folder:
"""Get the conversation history folder."""
def localfailures_folder(self) -> Folder:
"""Get the local failures folder."""
def recoverableitemsdeletions_folder(self) -> Folder:
"""Get the recoverable items deletions folder."""
def scheduled_folder(self) -> Folder:
"""Get the scheduled folder."""
def searchfolders_folder(self) -> Folder:
"""Get the search folders folder."""
def serverfailures_folder(self) -> Folder:
"""Get the server failures folder."""
def syncissues_folder(self) -> Folder:
"""Get the sync issues folder."""
# Message operations
def get_messages(self, limit: int = 25, *, query=None, order_by=None, batch=None, download_attachments: bool = False) -> list[Message]: ...
def get_message(self, object_id: str = None, query=None, *, download_attachments: bool = False) -> Message: ...
def new_message(self) -> Message: ...
def delete_message(self, message): ...
# Folder operations
def get_folders(self, limit: int = None, *, query=None, order_by=None, batch=None) -> list[Folder]: ...
def get_folder(self, *, folder_id: str = None, folder_name: str = None) -> Folder: ...
def create_child_folder(self, folder_name: str) -> Folder: ...
def refresh_folder(self, update_parent_if_changed: bool = False) -> bool: ...
def update_folder_name(self, name: str, update_folder_data: bool = True) -> bool: ...
def delete(self) -> bool: ...
def copy_folder(self, to_folder: Folder) -> Folder: ...
def move_folder(self, to_folder: Folder, *, update_parent_if_changed: bool = True) -> bool: ...
# Mailbox settings
def get_settings(self) -> MailboxSettings: ...
def set_automatic_reply(self, internal_text: str, external_text: str,
scheduled_start_date_time=None, scheduled_end_date_time=None,
externalAudience=None) -> bool: ...
def set_disable_reply(self) -> bool: ...Manage email folders including creation, deletion, and navigation.
def get_folders(self, limit: int = None, **filters) -> list[Folder]:
"""
Get mailbox folders.
Parameters:
- limit: maximum number of folders to return
- filters: additional OData filters
Returns:
- list[Folder]: List of folder objects
"""
def get_folder(self, folder_id: str = None, folder_name: str = None) -> Folder:
"""
Get a specific folder by ID or name.
Parameters:
- folder_id: folder identifier
- folder_name: folder display name
Returns:
- Folder: Folder object
"""
def new_folder(self, folder_name: str, parent_folder: Folder = None) -> Folder:
"""
Create a new folder.
Parameters:
- folder_name: name for the new folder
- parent_folder: parent folder (defaults to root)
Returns:
- Folder: Created folder object
"""
class Folder:
@property
def name(self) -> str:
"""Folder display name."""
@property
def total_item_count(self) -> int:
"""Total number of items in folder."""
@property
def unread_item_count(self) -> int:
"""Number of unread items in folder."""
def get_messages(self, limit: int = None, **filters) -> list[Message]:
"""Get messages from this folder."""
def move_to(self, to_folder: 'Folder') -> bool:
"""Move this folder to another parent folder."""
def delete(self) -> bool:
"""Delete this folder."""Retrieve, create, send, and manage email messages.
def get_messages(self, limit: int = None, download_attachments: bool = False, **filters) -> list[Message]:
"""
Get messages from the mailbox.
Parameters:
- limit: maximum number of messages to return
- download_attachments: whether to download message attachments
- filters: OData query filters (subject, sender, received_time, etc.)
Returns:
- list[Message]: List of message objects
"""
def new_message(self, to_recipients: list = None,
cc_recipients: list = None,
bcc_recipients: list = None) -> Message:
"""
Create a new message.
Parameters:
- to_recipients: list of recipient email addresses or Recipient objects
- cc_recipients: list of CC recipients
- bcc_recipients: list of BCC recipients
Returns:
- Message: New message object
"""
class Message:
@property
def subject(self) -> str:
"""Message subject line."""
@property
def body(self) -> str:
"""Message body content."""
@property
def sender(self) -> Recipient:
"""Message sender information."""
@property
def to_recipients(self) -> Recipients:
"""To recipients collection."""
@property
def received_time(self) -> datetime:
"""When the message was received."""
@property
def is_read(self) -> bool:
"""Whether the message has been read."""
@property
def importance(self) -> str:
"""Message importance level (Low, Normal, High)."""
def send(self) -> bool:
"""Send the message."""
def reply(self, to_all: bool = True) -> Message:
"""Create a reply to this message."""
def forward(self) -> Message:
"""Create a forward of this message."""
def mark_as_read(self) -> bool:
"""Mark the message as read."""
def mark_as_unread(self) -> bool:
"""Mark the message as unread."""
def delete(self) -> bool:
"""Delete this message."""
def move_to(self, folder: Folder) -> bool:
"""Move message to a specific folder."""Manage email attachments including upload, download, and inline attachments.
class MessageAttachments:
def __iter__(self) -> Iterator[MessageAttachment]:
"""Iterate over attachments."""
def download_attachments(self, to_path: str = None) -> bool:
"""
Download all attachments.
Parameters:
- to_path: directory to save attachments (defaults to current directory)
Returns:
- bool: True if all downloads successful
"""
def add(self, attachments: list) -> bool:
"""Add attachments to the message."""
class MessageAttachment:
@property
def name(self) -> str:
"""Attachment filename."""
@property
def size(self) -> int:
"""Attachment size in bytes."""
@property
def content_type(self) -> str:
"""MIME content type."""
@property
def is_inline(self) -> bool:
"""Whether attachment is inline."""
def download(self, to_path: str = None) -> str:
"""
Download the attachment.
Parameters:
- to_path: path to save the file
Returns:
- str: path to downloaded file
"""Advanced message search and filtering capabilities.
def search(self, search_text: str, folder: Folder = None) -> list[Message]:
"""
Search for messages.
Parameters:
- search_text: text to search for in subject/body
- folder: folder to search in (defaults to all folders)
Returns:
- list[Message]: Matching messages
"""
# Common filter examples for get_messages()
# By sender: sender='user@domain.com'
# By subject: subject__contains='Meeting'
# By date: received_time__gte=datetime(2023, 1, 1)
# Unread only: is_read=False
# With attachments: has_attachments=TrueOrganize messages with categories and flags.
class Message:
@property
def categories(self) -> list[str]:
"""Message categories."""
@property
def flag(self) -> dict:
"""Message flag information."""
def add_category(self, category: str) -> bool:
"""Add a category to the message."""
def remove_category(self, category: str) -> bool:
"""Remove a category from the message."""
def flag_message(self, flag_status: str = 'flagged') -> bool:
"""
Flag the message.
Parameters:
- flag_status: 'flagged', 'complete', or 'notFlagged'
Returns:
- bool: True if successful
"""from O365 import Account
account = Account(credentials)
mailbox = account.mailbox()
# Read recent emails
inbox = mailbox.inbox_folder
messages = inbox.get_messages(limit=10)
for message in messages:
print(f"From: {message.sender.address}")
print(f"Subject: {message.subject}")
print(f"Received: {message.received_time}")
print(f"Read: {message.is_read}")
print("---")# Create and send a new message
message = mailbox.new_message()
message.to_recipients.add('recipient@example.com')
message.subject = 'Test Message'
message.body = 'Hello from O365 Python library!'
# Add attachments
message.attachments.add(['document.pdf', 'image.jpg'])
# Send the message
if message.send():
print('Message sent successfully')from datetime import datetime, timedelta
# Search for unread messages from last week
last_week = datetime.now() - timedelta(days=7)
recent_unread = inbox.get_messages(
is_read=False,
received_time__gte=last_week,
limit=50
)
# Search for messages with specific subject
meeting_messages = inbox.get_messages(
subject__contains='Meeting',
limit=20
)
# Search messages from specific sender
sender_messages = inbox.get_messages(
sender='manager@company.com'
)# Create a new folder
projects_folder = mailbox.new_folder('Projects')
# Move messages to folder
for message in messages:
if 'project' in message.subject.lower():
message.move_to(projects_folder)
# Get folder statistics
print(f"Total items: {projects_folder.total_item_count}")
print(f"Unread items: {projects_folder.unread_item_count}")# Mailbox settings classes
class MailboxSettings:
automaticrepliessettings: AutomaticRepliesSettings
timezone: str
workinghours: dict
class AutomaticRepliesSettings:
external_reply_message: str
internal_reply_message: str
scheduled_start_date_time: datetime
scheduled_end_date_time: datetime
status: str # AutoReplyStatus
external_audience: str # ExternalAudience
# Enums for mailbox settings
class ExternalAudience:
NONE = "none"
CONTACTSONLY = "contactsOnly"
ALL = "all"
class AutoReplyStatus:
DISABLED = "disabled"
ALWAYSENABLED = "alwaysEnabled"
SCHEDULED = "scheduled"
# Message-related enums
class RecipientType:
TO = "to"
CC = "cc"
BCC = "bcc"
class Flag:
NOT_FLAGGED = "notFlagged"
COMPLETE = "complete"
FLAGGED = "flagged"
class Importance:
LOW = "low"
NORMAL = "normal"
HIGH = "high"
class MeetingMessageType:
NONE = "none"
MEETING_REQUEST = "meetingRequest"
MEETING_CANCELLED = "meetingCancelled"
MEETING_ACCEPTED = "meetingAccepted"
MEETING_TENTATIVELY_ACCEPTED = "meetingTentativelyAccepted"
MEETING_DECLINED = "meetingDeclined"Install with Tessl CLI
npx tessl i tessl/pypi-o365