Registry / communication / exchangelib

exchangelib

JSON →
library5.6.0pypypi✓ verified 25d ago

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.

pip install exchangelib
INSTALL
IMPORT
SIG · EXCHANGELIB
E
exchangelib
communicationpythonv5.6.0
Install
5.2s avg
Import
1619ms
Disk
69MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v5.6.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 1.688s · 69.7MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 5.2s · import 1.550s · 70MB
69MB installed
● package 69MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

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

This quickstart demonstrates how to connect to an Exchange mailbox using email/password credentials and autodiscovery. It then fetches and prints the subjects of the 5 most recent unread items in the inbox. It uses environment variables for security to avoid hardcoding sensitive information.

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.")
Debug
Known issues
breakingVersion 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.
fix
Migrate authentication logic to use `exchangelib.Credentials` directly. For custom protocols, ensure `auth_type` and other parameters are correctly passed to `Protocol`.
affects: >=5.0.0
breakingIn 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.
fix
Update any code that references `protocol.ews_url` (for autodiscover URL) to `protocol.autodiscover_url` and `protocol.service_endpoint` (for service endpoint URL) to `protocol.ews_url`.
affects: >=5.0.0
gotchaTime 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.
fix
Always use `exchangelib.EWSTimeZone` when creating or modifying datetime objects that interact with Exchange. Ensure your local system's timezone is correctly configured if relying on `tzlocal`.
affects: All
gotchaFetching all items from large folders (`folder.all()`) can be very slow and consume excessive memory. EWS APIs are often paginated.
fix
Use iterators or specify a maximum number of items when querying large folders (e.g., `folder.all().order_by('-datetime_received')[:100]`). For complex queries, use `folder.filter().iterator()`.
affects: All
gotchaAutodiscovery might fail in complex network environments or specific Exchange configurations. This prevents `Account` from establishing a connection.
fix
If autodiscovery fails, explicitly provide the `ews_url` when creating a `Configuration` object, then pass that configuration to the `Account`. Example: `config = Configuration(server='outlook.office365.com', credentials=credentials, ews_url='https://outlook.office365.com/EWS/Exchange.asmx')`.
affects: All
Errors
Common errors & fixes
exchangelib.errors.AutoDiscoverFailed: All steps in the autodiscover protocol failed
This error occurs when `exchangelib` cannot automatically determine the correct Exchange Web Services (EWS) endpoint for the given email address, often due to complex network configurations, non-standard EWS setups, or stricter server-side autodiscover policies.
fix
Manually specify the EWS server URL and disable autodiscover. You can often find the EWS URL in Outlook's connection settings or through your IT administrator.
```python
from exchangelib import Credentials, Account, Configuration

creds = Credentials(username='your_username@your_domain.com', password='your_password')
config = Configuration(server='your.exchange.server.com', credentials=creds) # e.g., 'outlook.office365.com' or a specific EWS URL
account = Account(primary_smtp_address='your_username@your_domain.com', config=config, autodiscover=False)
```
exchangelib.errors.UnauthorizedError: Invalid credentials for https://[domain]/EWS/Exchange.asmx
This error indicates that the provided username or password is incorrect, the authentication type used by `exchangelib` (e.g., NTLM, Basic, OAuth) does not match the server's requirements, or the account lacks the necessary permissions to access EWS. For Office 365, this often means Basic Authentication has been disabled, requiring a switch to OAuth2.
fix
First, double-check your username and password, including the format (e.g., `DOMAIN\username` vs. `user@domain.com`). If using Office 365, consider switching to OAuth2 authentication as Basic Auth is largely deprecated.
```python
from exchangelib import Credentials, Account, OAUTH2, OAuth2Credentials

# For NTLM/Basic Auth (if supported by your server)
# creds = Credentials(username='DOMAIN\username', password='your_password')

# For Office 365 / OAuth2
# Requires prior Azure AD app registration to get client_id, client_secret, and tenant_id
ocreds = OAuth2Credentials(
    client_id='your_client_id',
    client_secret='your_client_secret',
    tenant_id='your_tenant_id', # or 'organizations' or 'common'
    access_token='your_initial_access_token' # This needs to be refreshed externally
)

account = Account(primary_smtp_address='user@example.com', credentials=ocreds, autodiscover=True, access_type=OAUTH2)
```
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
This SSL error occurs when the Python environment cannot verify the SSL certificate presented by the Exchange server. This is common in corporate environments with custom root Certificate Authorities or self-signed certificates.
fix
To fix this, you can either explicitly trust the certificate by providing its path to `exchangelib` or, as a last resort for testing (not recommended for production), disable SSL verification.
```python
from exchangelib import DELEGATE, Account, Credentials, Configuration
from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter
import ssl

# Option 1: Provide path to CA bundle (recommended)
# BaseProtocol.HTTP_ADAPTER_CLS.ssl_context = ssl.create_default_context(cafile='/path/to/your/ca_bundle.pem')

# Option 2: Disable SSL verification (use with caution, for testing only)
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter

creds = Credentials(username='user@example.com', password='your_password')
account = Account(primary_smtp_address='user@example.com', credentials=creds, autodiscover=True)
```
exchangelib.errors.InvalidTypeError: 'tzinfo' <UTC> must be of type <class 'exchangelib.ewsdatetime.EWSTimeZone'>
`exchangelib` requires its specific `EWSTimeZone` objects for timezone-aware datetimes when interacting with EWS, rather than standard Python `datetime.tzinfo` or `pytz` timezone objects. This error typically arises when mixing different timezone object types.
fix
Always use `exchangelib.EWSTimeZone` and `exchangelib.EWSDateTime` when working with dates and times that will be sent to or received from Exchange.
```python
from exchangelib import EWSDateTime, EWSTimeZone
from datetime import datetime

# Correct way to create a timezone-aware EWSDateTime
tz = EWSTimeZone.localzone() # or EWSTimeZone.timezone('Europe/Copenhagen')
now = EWSDateTime.now(tz=tz)

# If you have a standard datetime object and need to convert it:
standard_dt = datetime.now(tz=pytz.utc) # Example with pytz
ews_tz = EWSTimeZone.from_timezone(standard_dt.tzinfo)
news_dt = EWSDateTime(standard_dt.year, standard_dt.month, standard_dt.day, 
                      standard_dt.hour, standard_dt.minute, standard_dt.second, 
                      tzinfo=news_tz)
```
ModuleNotFoundError: No module named 'exchangelib'
This fundamental Python error occurs when the `exchangelib` package is not installed in the Python environment where the script is being run, or if the environment path is misconfigured. It's also frequently encountered when deploying applications with tools like PyInstaller that might not correctly bundle all dependencies.
fix
Ensure `exchangelib` is installed in your environment using pip. If using a virtual environment, activate it first. If deploying with PyInstaller, ensure PyInstaller is correctly configured to include `exchangelib` as a hidden import if necessary.
```bash
pip install exchangelib

# If using PyInstaller and encountering issues, you might need:
pyinstaller --hidden-import exchangelib your_script.py
```
Upgrade
Version history
5.6.0latest on PyPI · released Oct 10, 2025
Audit
Dependencies
requestsrequiredHTTP client for making EWS requests.
requests-ntlmrequiredRequired for NTLM authentication with Exchange servers.
lxmlrequiredEfficient XML parsing and serialization for EWS SOAP messages.
dnspythonrequiredUsed for DNS lookups during autodiscovery of EWS endpoints.
pytzrequiredTimezone handling, especially for converting between local and EWS timezones.
tzlocalrequiredDetermines the local timezone for accurate timestamp conversions.
defusedxmlrequiredEnhanced security for XML parsing to prevent known vulnerabilities.
Agent activity
57 hits · last 30 days
node
54
OpenAI (training)
1
Resources