CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-office365-rest-python-client

Microsoft 365 & Microsoft Graph Library for Python

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

email-calendar.mddocs/

Email & Calendar Services

Outlook integration for email, calendar, contacts, and mailbox management through Microsoft Graph API with comprehensive messaging capabilities. Provides complete communication and scheduling functionality for Microsoft 365 environments.

Capabilities

Email Management

Comprehensive email operations including message composition, sending, receiving, organizing, and attachment management with support for rich content and advanced features.

class Message:
    """Outlook email message with comprehensive content and management capabilities."""
    
    # Core Properties
    id: str
    created_date_time: str
    last_modified_date_time: str
    change_key: str
    categories: List[str]
    received_date_time: str
    sent_date_time: str
    has_attachments: bool
    internet_message_id: str
    subject: str
    body_preview: str
    importance: str  # "low", "normal", "high"
    inference_classification: str
    is_delivery_receipt_requested: bool
    is_draft: bool
    is_read: bool
    is_read_receipt_requested: bool
    web_link: str
    
    def get(self) -> 'Message':
        """
        Retrieve message information and content.
        
        Returns:
            Message: Updated message object
        """
    
    def update(self) -> 'Message':
        """
        Update message properties.
        
        Returns:
            Message: Updated message object
        """
    
    def delete(self) -> None:
        """Delete message (move to Deleted Items)."""
    
    def send(self) -> None:
        """Send draft message."""
    
    def reply(self, comment: str = None) -> 'Message':
        """
        Create reply to message.
        
        Args:
            comment (str, optional): Reply comment
            
        Returns:
            Message: Reply message draft
        """
    
    def reply_all(self, comment: str = None) -> 'Message':
        """
        Create reply-all to message.
        
        Args:
            comment (str, optional): Reply comment
            
        Returns:
            Message: Reply-all message draft
        """
    
    def forward(self, comment: str = None, to_recipients: List[Dict[str, str]] = None) -> 'Message':
        """
        Create forward of message.
        
        Args:
            comment (str, optional): Forward comment
            to_recipients (List[Dict], optional): Forward recipients
            
        Returns:
            Message: Forward message draft
        """
    
    def copy(self, destination_id: str) -> 'Message':
        """
        Copy message to folder.
        
        Args:
            destination_id (str): Destination folder ID
            
        Returns:
            Message: Copied message
        """
    
    def move(self, destination_id: str) -> 'Message':
        """
        Move message to folder.
        
        Args:
            destination_id (str): Destination folder ID
            
        Returns:
            Message: Moved message
        """
    
    # Navigation Properties
    @property
    def body(self) -> 'ItemBody':
        """Message body content."""
    
    @property
    def from_(self) -> 'Recipient':
        """Message sender."""
    
    @property
    def sender(self) -> 'Recipient':
        """Message sender (may differ from from_ for delegates)."""
    
    @property
    def to_recipients(self) -> List['Recipient']:
        """Primary recipients."""
    
    @property
    def cc_recipients(self) -> List['Recipient']:
        """CC recipients."""
    
    @property
    def bcc_recipients(self) -> List['Recipient']:
        """BCC recipients."""
    
    @property
    def reply_to(self) -> List['Recipient']:
        """Reply-to recipients."""
    
    @property
    def attachments(self) -> 'AttachmentCollection':
        """Message attachments."""
    
    @property
    def extensions(self) -> 'ExtensionCollection':
        """Message extensions."""

class MessageCollection:
    """Collection of email messages with query and management capabilities."""
    
    def get(self) -> 'MessageCollection':
        """Retrieve collection of messages."""
    
    def filter(self, expression: str) -> 'MessageCollection':
        """
        Filter messages by OData expression.
        
        Args:
            expression (str): OData filter expression
            
        Returns:
            MessageCollection: Filtered collection
        """
    
    def select(self, properties: List[str]) -> 'MessageCollection':
        """
        Select specific properties to retrieve.
        
        Args:
            properties (List[str]): Property names to select
            
        Returns:
            MessageCollection: Collection with selected properties
        """
    
    def top(self, count: int) -> 'MessageCollection':
        """
        Limit results to top N messages.
        
        Args:
            count (int): Maximum number of messages
            
        Returns:
            MessageCollection: Limited collection
        """
    
    def order_by(self, property_name: str, ascending: bool = True) -> 'MessageCollection':
        """
        Sort messages by property.
        
        Args:
            property_name (str): Property to sort by
            ascending (bool): Sort direction
            
        Returns:
            MessageCollection: Sorted collection
        """
    
    def get_by_id(self, message_id: str) -> Message:
        """
        Get message by ID.
        
        Args:
            message_id (str): Message unique identifier
            
        Returns:
            Message: Message object
        """
    
    def add(self, message_info: Dict[str, Any]) -> Message:
        """
        Create new message (draft).
        
        Args:
            message_info (Dict): Message properties
            
        Returns:
            Message: Created message draft
        """
    
    def send_mail(self, message: Dict[str, Any], save_to_sent_items: bool = True) -> None:
        """
        Send message directly without creating draft.
        
        Args:
            message (Dict): Message content and recipients
            save_to_sent_items (bool): Save copy to Sent Items
        """

Mail Folder Management

Email folder organization with support for custom folders, folder hierarchy, and message organization rules.

class MailFolder:
    """Outlook mail folder with comprehensive message organization capabilities."""
    
    # Core Properties
    id: str
    display_name: str
    parent_folder_id: str
    child_folder_count: int
    unread_item_count: int
    total_item_count: int
    size_in_bytes: int
    is_hidden: bool
    
    def get(self) -> 'MailFolder':
        """
        Retrieve folder information.
        
        Returns:
            MailFolder: Updated folder object
        """
    
    def update(self) -> 'MailFolder':
        """
        Update folder properties.
        
        Returns:
            MailFolder: Updated folder object
        """
    
    def delete(self) -> None:
        """Delete folder and all contents."""
    
    def copy(self, destination_id: str) -> 'MailFolder':
        """
        Copy folder to destination.
        
        Args:
            destination_id (str): Destination folder ID
            
        Returns:
            MailFolder: Copied folder
        """
    
    def move(self, destination_id: str) -> 'MailFolder':
        """
        Move folder to destination.
        
        Args:
            destination_id (str): Destination folder ID
            
        Returns:
            MailFolder: Moved folder
        """
    
    # Navigation Properties
    @property
    def messages(self) -> MessageCollection:
        """Messages in the folder."""
    
    @property
    def child_folders(self) -> 'MailFolderCollection':
        """Child folders."""
    
    @property
    def message_rules(self) -> 'MessageRuleCollection':
        """Message rules for the folder."""

class MailFolderCollection:
    """Collection of mail folders with management capabilities."""
    
    def get(self) -> 'MailFolderCollection':
        """Retrieve collection of folders."""
    
    def filter(self, expression: str) -> 'MailFolderCollection':
        """
        Filter folders by expression.
        
        Args:
            expression (str): OData filter expression
            
        Returns:
            MailFolderCollection: Filtered collection
        """
    
    def get_by_id(self, folder_id: str) -> MailFolder:
        """
        Get folder by ID.
        
        Args:
            folder_id (str): Folder unique identifier
            
        Returns:
            MailFolder: Folder object
        """
    
    def add(self, folder_info: Dict[str, Any]) -> MailFolder:
        """
        Create new folder.
        
        Args:
            folder_info (Dict): Folder properties
            
        Returns:
            MailFolder: Created folder
        """

Calendar Management

Comprehensive calendar functionality including event creation, scheduling, meeting management, and calendar sharing with support for recurring events and attendee management.

class Calendar:
    """Outlook calendar with comprehensive scheduling and event management."""
    
    # Core Properties
    id: str
    name: str
    color: str
    change_key: str
    can_share: bool
    can_view_private_items: bool
    can_edit: bool
    allowed_online_meeting_providers: List[str]
    default_online_meeting_provider: str
    is_tale_enabled: bool
    is_removable: bool
    
    def get(self) -> 'Calendar':
        """
        Retrieve calendar information.
        
        Returns:
            Calendar: Updated calendar object
        """
    
    def update(self) -> 'Calendar':
        """
        Update calendar properties.
        
        Returns:
            Calendar: Updated calendar object
        """
    
    def delete(self) -> None:
        """Delete calendar."""
    
    def get_schedule(self, schedules: List[str], start_time: str, end_time: str, availability_view_interval: int = 60) -> List[Dict[str, Any]]:
        """
        Get free/busy information for specified time range.
        
        Args:
            schedules (List[str]): Email addresses to check
            start_time (str): Start time (ISO 8601)
            end_time (str): End time (ISO 8601)
            availability_view_interval (int): Interval in minutes
            
        Returns:
            List[Dict]: Free/busy information
        """
    
    # Navigation Properties
    @property
    def events(self) -> 'EventCollection':
        """Events in the calendar."""
    
    @property
    def calendar_view(self) -> 'EventCollection':
        """Calendar view of events."""

class CalendarCollection:
    """Collection of calendars with management capabilities."""
    
    def get(self) -> 'CalendarCollection':
        """Retrieve collection of calendars."""
    
    def get_by_id(self, calendar_id: str) -> Calendar:
        """
        Get calendar by ID.
        
        Args:
            calendar_id (str): Calendar unique identifier
            
        Returns:
            Calendar: Calendar object
        """
    
    def add(self, calendar_info: Dict[str, Any]) -> Calendar:
        """
        Create new calendar.
        
        Args:
            calendar_info (Dict): Calendar properties
            
        Returns:
            Calendar: Created calendar
        """

class Event:
    """Calendar event with comprehensive scheduling and attendee management."""
    
    # Core Properties
    id: str
    created_date_time: str
    last_modified_date_time: str
    change_key: str
    categories: List[str]
    original_start_time_zone: str
    original_end_time_zone: str
    i_cal_u_id: str
    reminder_minutes_before_start: int
    is_reminder_on: bool
    has_attachments: bool
    subject: str
    importance: str
    sensitivity: str
    is_all_day: bool
    is_cancelled: bool
    is_organizer: bool
    response_requested: bool
    series_master_id: str
    show_as: str  # "free", "tentative", "busy", "oof", "workingElsewhere"
    type: str  # "singleInstance", "occurrence", "exception", "seriesMaster"
    web_link: str
    
    def get(self) -> 'Event':
        """
        Retrieve event information.
        
        Returns:
            Event: Updated event object
        """
    
    def update(self) -> 'Event':
        """
        Update event properties.
        
        Returns:
            Event: Updated event object
        """
    
    def delete(self) -> None:
        """Delete event."""
    
    def accept(self, comment: str = None, send_response: bool = True) -> None:
        """
        Accept meeting invitation.
        
        Args:
            comment (str, optional): Response comment
            send_response (bool): Send response to organizer
        """
    
    def decline(self, comment: str = None, send_response: bool = True) -> None:
        """
        Decline meeting invitation.
        
        Args:
            comment (str, optional): Response comment
            send_response (bool): Send response to organizer
        """
    
    def tentatively_accept(self, comment: str = None, send_response: bool = True) -> None:
        """
        Tentatively accept meeting invitation.
        
        Args:
            comment (str, optional): Response comment
            send_response (bool): Send response to organizer
        """
    
    def cancel(self, comment: str = None) -> None:
        """
        Cancel event (organizer only).
        
        Args:
            comment (str, optional): Cancellation comment
        """
    
    def dismiss_reminder(self) -> None:
        """Dismiss event reminder."""
    
    def snooze_reminder(self, new_reminder_time: str) -> None:
        """
        Snooze event reminder.
        
        Args:
            new_reminder_time (str): New reminder time (ISO 8601)
        """
    
    def forward(self, to_recipients: List[Dict[str, str]], comment: str = None) -> None:
        """
        Forward meeting invitation.
        
        Args:
            to_recipients (List[Dict]): Recipients to forward to
            comment (str, optional): Forward comment
        """
    
    # Navigation Properties
    @property
    def body(self) -> 'ItemBody':
        """Event body content."""
    
    @property
    def start(self) -> 'DateTimeTimeZone':
        """Event start time."""
    
    @property
    def end(self) -> 'DateTimeTimeZone':
        """Event end time."""
    
    @property
    def location(self) -> 'Location':
        """Event location."""
    
    @property
    def locations(self) -> List['Location']:
        """Multiple event locations."""
    
    @property
    def attendees(self) -> List['Attendee']:
        """Event attendees."""
    
    @property
    def organizer(self) -> 'Recipient':
        """Event organizer."""
    
    @property
    def recurrence(self) -> 'PatternedRecurrence':
        """Event recurrence pattern."""
    
    @property
    def attachments(self) -> 'AttachmentCollection':
        """Event attachments."""
    
    @property
    def online_meeting(self) -> 'OnlineMeetingInfo':
        """Online meeting information."""
    
    @property
    def instances(self) -> 'EventCollection':
        """Event instances (for recurring events)."""

class EventCollection:
    """Collection of calendar events with query and management capabilities."""
    
    def get(self) -> 'EventCollection':
        """Retrieve collection of events."""
    
    def filter(self, expression: str) -> 'EventCollection':
        """
        Filter events by expression.
        
        Args:
            expression (str): OData filter expression
            
        Returns:
            EventCollection: Filtered collection
        """
    
    def select(self, properties: List[str]) -> 'EventCollection':
        """
        Select specific properties.
        
        Args:
            properties (List[str]): Property names to select
            
        Returns:
            EventCollection: Collection with selected properties
        """
    
    def top(self, count: int) -> 'EventCollection':
        """
        Limit results to top N events.
        
        Args:
            count (int): Maximum number of events
            
        Returns:
            EventCollection: Limited collection
        """
    
    def order_by(self, property_name: str, ascending: bool = True) -> 'EventCollection':
        """
        Sort events by property.
        
        Args:
            property_name (str): Property to sort by
            ascending (bool): Sort direction
            
        Returns:
            EventCollection: Sorted collection
        """
    
    def get_by_id(self, event_id: str) -> Event:
        """
        Get event by ID.
        
        Args:
            event_id (str): Event unique identifier
            
        Returns:
            Event: Event object
        """
    
    def add(self, event_info: Dict[str, Any]) -> Event:
        """
        Create new event.
        
        Args:
            event_info (Dict): Event properties
            
        Returns:
            Event: Created event
        """

Attachment Management

File and item attachment support with comprehensive attachment handling for both email messages and calendar events.

class Attachment:
    """Base attachment class with common properties and operations."""
    
    # Core Properties
    id: str
    last_modified_date_time: str
    name: str
    content_type: str
    size: int
    is_inline: bool
    
    def get(self) -> 'Attachment':
        """
        Retrieve attachment information.
        
        Returns:
            Attachment: Updated attachment object
        """
    
    def delete(self) -> None:
        """Delete attachment."""

class FileAttachment(Attachment):
    """File attachment with content access."""
    
    # Additional Properties
    content_id: str
    content_location: str
    content_bytes: bytes
    
    def get_content(self) -> bytes:
        """
        Get attachment content.
        
        Returns:
            bytes: Attachment content as bytes
        """

class ItemAttachment(Attachment):
    """Outlook item attachment (message, event, contact)."""
    
    # Navigation Properties
    @property
    def item(self) -> 'OutlookItem':
        """Attached Outlook item."""

class ReferenceAttachment(Attachment):
    """Reference attachment pointing to cloud content."""
    
    # Additional Properties
    source_url: str
    provider_type: str
    thumbnail_url: str
    preview_url: str
    permission: str
    is_folder: bool

class AttachmentCollection:
    """Collection of attachments with management capabilities."""
    
    def get(self) -> 'AttachmentCollection':
        """Retrieve collection of attachments."""
    
    def get_by_id(self, attachment_id: str) -> Attachment:
        """
        Get attachment by ID.
        
        Args:
            attachment_id (str): Attachment unique identifier
            
        Returns:
            Attachment: Attachment object
        """
    
    def add(self, attachment_info: Dict[str, Any]) -> Attachment:
        """
        Add new attachment.
        
        Args:
            attachment_info (Dict): Attachment properties and content
            
        Returns:
            Attachment: Created attachment
        """

Usage Examples

Email Operations

from office365.graph_client import GraphClient

client = GraphClient.with_client_secret(client_id, client_secret, tenant)

# Get user's messages
messages = client.me.messages.top(10).get().execute_query()
for message in messages:
    print(f"From: {message.from_['emailAddress']['name']}, Subject: {message.subject}")

# Send email
message_info = {
    "subject": "Project Update",
    "body": {
        "contentType": "html",
        "content": "<h1>Project Status</h1><p>The project is on track for completion next week.</p>"
    },
    "toRecipients": [
        {
            "emailAddress": {
                "address": "colleague@company.com",
                "name": "Colleague Name"
            }
        }
    ]
}

client.me.send_mail(message_info, save_to_sent_items=True).execute_query()
print("Email sent successfully")

# Create draft with attachment
draft_info = {
    "subject": "Report with Attachment",
    "body": {
        "contentType": "text",
        "content": "Please find the attached report."
    },
    "toRecipients": [
        {"emailAddress": {"address": "manager@company.com"}}
    ]
}

draft = client.me.messages.add(draft_info).execute_query()

# Add file attachment
with open("report.pdf", "rb") as file_content:
    attachment_info = {
        "@odata.type": "#microsoft.graph.fileAttachment",
        "name": "monthly_report.pdf",
        "contentType": "application/pdf",
        "contentBytes": file_content.read()
    }
    draft.attachments.add(attachment_info).execute_query()

# Send draft
draft.send().execute_query()

Calendar Operations

# Get user's calendar events
events = client.me.events.filter("start/dateTime ge '2024-01-01T00:00:00Z'").top(5).get().execute_query()
for event in events:
    print(f"Event: {event.subject}, Start: {event.start['dateTime']}")

# Create calendar event
event_info = {
    "subject": "Team Meeting",
    "body": {
        "contentType": "html",
        "content": "Weekly team sync meeting"
    },
    "start": {
        "dateTime": "2024-02-15T10:00:00",
        "timeZone": "UTC"
    },
    "end": {
        "dateTime": "2024-02-15T11:00:00",
        "timeZone": "UTC"
    },
    "location": {
        "displayName": "Conference Room A"
    },
    "attendees": [
        {
            "emailAddress": {
                "address": "team@company.com",
                "name": "Team Members"
            },
            "type": "required"
        }
    ],
    "reminderMinutesBeforeStart": 15,
    "recurrence": {
        "pattern": {
            "type": "weekly",
            "interval": 1,
            "daysOfWeek": ["thursday"]
        },
        "range": {
            "type": "endDate",
            "startDate": "2024-02-15",
            "endDate": "2024-06-15"
        }
    }
}

new_event = client.me.events.add(event_info).execute_query()
print(f"Created recurring event: {new_event.subject}")

Mail Folder Management

# Get mail folders
folders = client.me.mail_folders.get().execute_query()
for folder in folders:
    print(f"Folder: {folder.display_name}, Unread: {folder.unread_item_count}")

# Create custom folder
folder_info = {
    "displayName": "Project Communications"
}
new_folder = client.me.mail_folders.add(folder_info).execute_query()

# Move messages to folder
inbox = client.me.mail_folders.filter("displayName eq 'Inbox'").get().execute_query()[0]
project_messages = inbox.messages.filter("contains(subject, 'Project Alpha')").get().execute_query()

for message in project_messages:
    message.move(new_folder.id).execute_query()
    print(f"Moved message: {message.subject}")

Types

from typing import Dict, List, Any, Optional

class ItemBody:
    """Content body for messages and events."""
    
    content_type: str  # "text" or "html"
    content: str

class Recipient:
    """Email recipient information."""
    
    email_address: Dict[str, str]  # {"name": str, "address": str}

class DateTimeTimeZone:
    """Date and time with timezone information."""
    
    date_time: str  # ISO 8601 format
    time_zone: str  # Timezone identifier

class Location:
    """Event location information."""
    
    display_name: str
    location_email_address: str
    address: Dict[str, str]
    coordinates: Dict[str, float]
    location_uri: str
    location_type: str
    unique_id: str
    unique_id_type: str

class Attendee:
    """Event attendee with response information."""
    
    type: str  # "required", "optional", "resource"
    status: Dict[str, str]  # {"response": str, "time": str}
    email_address: Dict[str, str]

class PatternedRecurrence:
    """Event recurrence pattern."""
    
    pattern: Dict[str, Any]  # Recurrence pattern details
    range: Dict[str, Any]    # Recurrence range details

class RecurrencePattern:
    """Recurrence pattern details."""
    
    type: str  # "daily", "weekly", "monthly", etc.
    interval: int
    month: int
    day_of_month: int
    days_of_week: List[str]
    first_day_of_week: str
    index: str

class RecurrenceRange:
    """Recurrence range details."""
    
    type: str  # "endDate", "noEnd", "numbered"
    start_date: str
    end_date: str
    recurrence_time_zone: str
    number_of_occurrences: int

class OnlineMeetingInfo:
    """Online meeting information for events."""
    
    conference_id: str
    join_url: str
    phones: List[Dict[str, str]]
    quick_dial: str
    toll_free_numbers: List[str]
    toll_number: str

class MessageRule:
    """Email rule for automatic message processing."""
    
    id: str
    display_name: str
    sequence: int
    is_enabled: bool
    has_error: bool
    conditions: Dict[str, Any]
    actions: Dict[str, Any]
    exceptions: Dict[str, Any]

class MailboxSettings:
    """User mailbox configuration settings."""
    
    archive_folder: str
    automatic_replies_setting: Dict[str, Any]
    date_format: str
    delegate_meeting_message_delivery_options: str
    language: Dict[str, str]
    time_format: str
    time_zone: str
    working_hours: Dict[str, Any]

Install with Tessl CLI

npx tessl i tessl/pypi-office365-rest-python-client

docs

authentication.md

directory-services.md

email-calendar.md

index.md

onedrive-files.md

sharepoint-sites.md

teams.md

tile.json