Exchangelib
Exchangelib is a Python client for Microsoft Exchange Web Services (EWS), providing programmatic access to Exchange mailboxes, calendars, contacts, and tasks. It supports autodiscovery, various authentication methods (NTLM, OAuth), and aims to be a comprehensive, easy-to-use interface for EWS. The current version is 5.6.0, with a release cadence that responds to bug fixes, feature requests, and EWS changes.
Warnings
- breaking Version 5.0.0 removed `BasicAuth` as a standalone class. Authentication details are now handled directly by the `Credentials` class or implicitly by the `Protocol` class. Custom protocol definitions must be updated.
- breaking In version 5.0.0, the `protocol.ews_url` attribute was renamed to `protocol.autodiscover_url` for clarity. The attribute that points to the actual EWS service endpoint is now `protocol.ews_url` (previously `protocol.service_endpoint`). This affects direct manipulation or inspection of `Protocol` objects.
- gotcha Time zone handling can be complex with EWS, especially when dealing with recurring events or ensuring consistent timestamps across systems. EWS often expects UTC or specific EWS timezones.
- gotcha Fetching all items from large folders (`folder.all()`) can be very slow and consume excessive memory. EWS APIs are often paginated.
- gotcha Autodiscovery might fail in complex network environments or specific Exchange configurations. This prevents `Account` from establishing a connection.
Install
-
pip install exchangelib
Imports
- Account
from exchangelib import Account
- Credentials
from exchangelib import Credentials
- Configuration
from exchangelib import Configuration
- DELEGATE
from exchangelib import DELEGATE
- EWSTimeZone
from exchangelib import EWSTimeZone
- IMPERSONATION
from exchangelib import IMPERSONATION
- Message
from exchangelib import Message
- Mailbox
from exchangelib import Mailbox
- Folder
from exchangelib import Folder
Quickstart
import os
from exchangelib import Account, Credentials, Configuration, DELEGATE
# Get credentials from environment variables for security
email = os.environ.get('EXCHANGE_EMAIL', 'your_email@example.com')
password = os.environ.get('EXCHANGE_PASSWORD', 'your_password')
if not email or not password or email == 'your_email@example.com':
print("Please set EXCHANGE_EMAIL and EXCHANGE_PASSWORD environment variables.")
print("Or replace placeholders directly in the script (not recommended for production).")
exit(1)
credentials = Credentials(email, password)
try:
# Autodiscover the EWS URL and connect
account = Account(
primary_smtp_address=email,
credentials=credentials,
autodiscover=True,
access_type=DELEGATE # Or IMPERSONATION, ARCHIVE, etc.
)
print(f"Successfully connected to Exchange for {account.primary_smtp_address}")
print(f"EWS URL: {account.protocol.ews_url}")
# Example: List subjects of 5 most recent unread items in Inbox
inbox = account.inbox
print(f"\nListing up to 5 unread items in Inbox for {email}:")
for item in inbox.filter(is_read=False).order_by('-datetime_received')[:5]:
print(f"- Subject: {item.subject}, From: {item.sender.email_address}, Received: {item.datetime_received}")
except Exception as e:
print(f"Could not connect or perform operation: {e}")
print("Common issues: Incorrect credentials, firewall blocking EWS, autodiscovery failure.")
print("If autodiscovery fails, try setting `autodiscover=False` and `ews_url` manually in Configuration.")