Client for Microsoft Exchange Web Services (EWS) providing Django-style ORM interface for Exchange mailboxes.
—
Full calendar functionality for creating, updating, and managing appointments, meetings, and recurring events. Includes support for attendees, meeting requests, and complex recurrence patterns.
The CalendarItem class represents appointments, meetings, and calendar events with comprehensive scheduling features.
class CalendarItem:
def __init__(
self,
account: Account = None,
folder: Folder = None,
**kwargs
):
"""
Create a new calendar item.
Parameters:
- account: Account the item belongs to
- folder: Calendar folder to save the item in
- **kwargs: Calendar item properties
"""
# Basic properties
subject: str
body: Body | HTMLBody
start: EWSDateTime
end: EWSDateTime
location: str
is_all_day: bool
# Meeting properties
organizer: Mailbox
required_attendees: list[Attendee]
optional_attendees: list[Attendee]
resources: list[Attendee]
# Status and response
my_response_type: str # 'NoResponseReceived', 'Organizer', 'Tentative', 'Accept', 'Decline'
response_requested: bool
# Meeting settings
allow_new_time_proposal: bool
is_online_meeting: bool
meeting_workspace_url: str
net_show_url: str
# Recurrence
recurrence: Recurrence
# Categories and importance
categories: list[str]
importance: str
sensitivity: str
# Status
legacy_free_busy_status: str # 'Free', 'Tentative', 'Busy', 'OOF', 'NoData'
show_as: str # Same as legacy_free_busy_status
# Reminders
reminder_is_set: bool
reminder_minutes_before_start: int
# Time zones
start_timezone: EWSTimeZone
end_timezone: EWSTimeZoneCreate and manage meetings with attendees and meeting requests.
class CalendarItem:
def save(
self,
send_meeting_invitations: str = 'SendToNone',
update_fields: list = None
):
"""
Save the calendar item.
Parameters:
- send_meeting_invitations: 'SendToNone', 'SendOnlyToAll', 'SendToAllAndSaveCopy'
- update_fields: List of specific fields to update
"""
def delete(
self,
delete_type: str = 'MoveToDeletedItems',
send_meeting_cancellations: str = 'SendToNone'
):
"""
Delete the calendar item.
Parameters:
- delete_type: Type of deletion
- send_meeting_cancellations: How to handle meeting cancellations
"""
def cancel(self, body: str | Body | HTMLBody = None):
"""
Cancel the meeting and send cancellation notices.
Parameters:
- body: Cancellation message body
"""Usage example:
from exchangelib import CalendarItem, Attendee, Mailbox, EWSDateTime, HTMLBody
from datetime import datetime, timedelta
# Create a meeting
start_time = EWSDateTime.from_datetime(datetime.now() + timedelta(days=1))
end_time = start_time + timedelta(hours=1)
meeting = CalendarItem(
account=account,
folder=account.calendar,
subject='Project Planning Meeting',
body=HTMLBody('<p>Let\'s discuss the Q4 project timeline.</p>'),
start=start_time,
end=end_time,
location='Conference Room A',
required_attendees=[
Attendee(mailbox=Mailbox(email_address='manager@company.com')),
Attendee(mailbox=Mailbox(email_address='colleague@company.com'))
],
optional_attendees=[
Attendee(mailbox=Mailbox(email_address='consultant@company.com'))
]
)
meeting.save(send_meeting_invitations='SendToAllAndSaveCopy')Handle meeting invitations and responses.
class CalendarItem:
def accept(
self,
body: str | Body | HTMLBody = None,
tentative: bool = False
) -> AcceptItem | TentativelyAcceptItem:
"""
Accept a meeting invitation.
Parameters:
- body: Response message body
- tentative: Whether to accept tentatively
Returns:
AcceptItem or TentativelyAcceptItem response object
"""
def decline(self, body: str | Body | HTMLBody = None) -> DeclineItem:
"""
Decline a meeting invitation.
Parameters:
- body: Response message body
Returns:
DeclineItem response object
"""
def tentatively_accept(self, body: str | Body | HTMLBody = None) -> TentativelyAcceptItem:
"""
Tentatively accept a meeting invitation.
Parameters:
- body: Response message body
Returns:
TentativelyAcceptItem response object
"""Manage meeting attendees with response tracking.
class Attendee:
def __init__(
self,
mailbox: Mailbox,
response_type: str = 'NoResponseReceived'
):
"""
Create a meeting attendee.
Parameters:
- mailbox: Attendee's mailbox
- response_type: Response status
"""
mailbox: Mailbox
response_type: str # 'NoResponseReceived', 'Organizer', 'Tentative', 'Accept', 'Decline'
last_response_time: EWSDateTimeUsage example:
from exchangelib import Attendee, Mailbox
# Create attendees with different roles
required_attendees = [
Attendee(
mailbox=Mailbox(
email_address='john@company.com',
name='John Smith'
)
),
Attendee(
mailbox=Mailbox(
email_address='jane@company.com',
name='Jane Doe'
)
)
]
optional_attendees = [
Attendee(
mailbox=Mailbox(
email_address='consultant@external.com',
name='External Consultant'
)
)
]
# Add to calendar item
meeting.required_attendees = required_attendees
meeting.optional_attendees = optional_attendeesCreate and manage recurring calendar events with complex patterns.
class Recurrence:
def __init__(
self,
pattern: RecurrencePattern,
boundary: RecurrenceBoundary
):
"""
Define recurrence for a calendar item.
Parameters:
- pattern: How often the event recurs
- boundary: When the recurrence ends
"""
pattern: RecurrencePattern
boundary: RecurrenceBoundary
class DailyRecurrence:
def __init__(self, interval: int = 1):
"""Daily recurrence pattern."""
class WeeklyRecurrence:
def __init__(
self,
interval: int = 1,
weekdays: list[str] = None,
first_day_of_week: str = 'Monday'
):
"""Weekly recurrence pattern."""
class MonthlyRecurrence:
def __init__(self, interval: int = 1, day_of_month: int = 1):
"""Monthly recurrence pattern."""
class YearlyRecurrence:
def __init__(self, interval: int = 1, month: int = 1, day_of_month: int = 1):
"""Yearly recurrence pattern."""
class EndDateRecurrenceBoundary:
def __init__(self, end: EWSDate):
"""End recurrence on a specific date."""
class NoEndRecurrenceBoundary:
def __init__(self):
"""Recurrence with no end date."""
class NumberedRecurrenceBoundary:
def __init__(self, number_of_occurrences: int):
"""End recurrence after a specific number of occurrences."""Usage example:
from exchangelib.recurrence import WeeklyRecurrence, EndDateRecurrenceBoundary, Recurrence
from exchangelib import EWSDate
from datetime import date, timedelta
# Create a weekly recurring meeting
weekly_pattern = WeeklyRecurrence(
interval=1, # Every week
weekdays=['Monday', 'Wednesday', 'Friday']
)
end_boundary = EndDateRecurrenceBoundary(
end=EWSDate.from_date(date.today() + timedelta(days=90))
)
recurring_meeting = CalendarItem(
account=account,
folder=account.calendar,
subject='Daily Standup',
start=EWSDateTime.from_datetime(datetime.now().replace(hour=9, minute=0)),
end=EWSDateTime.from_datetime(datetime.now().replace(hour=9, minute=30)),
location='Team Room',
recurrence=Recurrence(pattern=weekly_pattern, boundary=end_boundary)
)
recurring_meeting.save(send_meeting_invitations='SendToAllAndSaveCopy')Create and manage all-day calendar events.
class CalendarItem:
is_all_day: bool
def create_all_day_event(
subject: str,
start_date: EWSDate,
end_date: EWSDate = None,
**kwargs
):
"""
Create an all-day event.
Parameters:
- subject: Event subject
- start_date: Start date
- end_date: End date (defaults to same as start_date)
- **kwargs: Additional event properties
"""Usage example:
from exchangelib import EWSDate
from datetime import date
# Create an all-day event
all_day_event = CalendarItem(
account=account,
folder=account.calendar,
subject='Company Holiday',
start=EWSDateTime.from_date(date.today() + timedelta(days=30)),
end=EWSDateTime.from_date(date.today() + timedelta(days=31)),
is_all_day=True,
show_as='Free',
categories=['Holiday']
)
all_day_event.save()Manage calendar availability and free/busy status.
class CalendarItem:
show_as: str # 'Free', 'Tentative', 'Busy', 'OOF' (Out of Office)
legacy_free_busy_status: str # Same values as show_as
def get_free_busy_info(
start: EWSDateTime,
end: EWSDateTime,
requested_view: str = 'Detailed'
):
"""
Get free/busy information for a time period.
Parameters:
- start: Start time
- end: End time
- requested_view: Level of detail ('FreeBusy', 'Detailed')
Returns:
Free/busy information
"""Book meeting rooms and resources.
class Room:
def __init__(self, email_address: str, name: str = None):
"""
Meeting room representation.
Parameters:
- email_address: Room's email address
- name: Room display name
"""
class RoomList:
def __init__(self, email_address: str, name: str = None):
"""
Room list representation.
Parameters:
- email_address: Room list email address
- name: Room list name
"""
def get_rooms(self) -> list[Room]:
"""Get all rooms in this room list."""Usage example:
from exchangelib import Room, Attendee
# Book a conference room
conference_room = Room(
email_address='conference-room-a@company.com',
name='Conference Room A'
)
meeting_with_room = CalendarItem(
account=account,
folder=account.calendar,
subject='Board Meeting',
start=start_time,
end=end_time,
location='Conference Room A',
resources=[
Attendee(mailbox=conference_room)
]
)
meeting_with_room.save(send_meeting_invitations='SendToAllAndSaveCopy')Special calendar response item types for meeting management.
class AcceptItem:
def __init__(self, reference_item_id: ItemId, **kwargs):
"""Accept a meeting request."""
def send(self):
"""Send the acceptance response."""
class DeclineItem:
def __init__(self, reference_item_id: ItemId, **kwargs):
"""Decline a meeting request."""
def send(self):
"""Send the decline response."""
class TentativelyAcceptItem:
def __init__(self, reference_item_id: ItemId, **kwargs):
"""Tentatively accept a meeting request."""
def send(self):
"""Send the tentative acceptance response."""
class CancelCalendarItem:
def __init__(self, reference_item_id: ItemId, **kwargs):
"""Cancel a calendar item."""
def send(self):
"""Send the cancellation."""Install with Tessl CLI
npx tessl i tessl/pypi-exchangelib