{"id":3481,"library":"exchangelib","title":"Exchangelib","description":"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.","status":"active","version":"5.6.0","language":"en","source_language":"en","source_url":"https://github.com/ecederstrand/exchangelib.git","tags":["exchange","ews","microsoft","email","calendar","outlook"],"install":[{"cmd":"pip install exchangelib","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"HTTP client for making EWS requests.","package":"requests"},{"reason":"Required for NTLM authentication with Exchange servers.","package":"requests-ntlm"},{"reason":"Efficient XML parsing and serialization for EWS SOAP messages.","package":"lxml"},{"reason":"Used for DNS lookups during autodiscovery of EWS endpoints.","package":"dnspython"},{"reason":"Timezone handling, especially for converting between local and EWS timezones.","package":"pytz"},{"reason":"Determines the local timezone for accurate timestamp conversions.","package":"tzlocal"},{"reason":"Enhanced security for XML parsing to prevent known vulnerabilities.","package":"defusedxml"}],"imports":[{"symbol":"Account","correct":"from exchangelib import Account"},{"symbol":"Credentials","correct":"from exchangelib import Credentials"},{"symbol":"Configuration","correct":"from exchangelib import Configuration"},{"symbol":"DELEGATE","correct":"from exchangelib import DELEGATE"},{"symbol":"EWSTimeZone","correct":"from exchangelib import EWSTimeZone"},{"symbol":"IMPERSONATION","correct":"from exchangelib import IMPERSONATION"},{"symbol":"Message","correct":"from exchangelib import Message"},{"symbol":"Mailbox","correct":"from exchangelib import Mailbox"},{"symbol":"Folder","correct":"from exchangelib import Folder"}],"quickstart":{"code":"import os\nfrom exchangelib import Account, Credentials, Configuration, DELEGATE\n\n# Get credentials from environment variables for security\nemail = os.environ.get('EXCHANGE_EMAIL', 'your_email@example.com')\npassword = os.environ.get('EXCHANGE_PASSWORD', 'your_password')\n\nif not email or not password or email == 'your_email@example.com':\n    print(\"Please set EXCHANGE_EMAIL and EXCHANGE_PASSWORD environment variables.\")\n    print(\"Or replace placeholders directly in the script (not recommended for production).\")\n    exit(1)\n\ncredentials = Credentials(email, password)\n\ntry:\n    # Autodiscover the EWS URL and connect\n    account = Account(\n        primary_smtp_address=email,\n        credentials=credentials,\n        autodiscover=True,\n        access_type=DELEGATE # Or IMPERSONATION, ARCHIVE, etc.\n    )\n    print(f\"Successfully connected to Exchange for {account.primary_smtp_address}\")\n    print(f\"EWS URL: {account.protocol.ews_url}\")\n\n    # Example: List subjects of 5 most recent unread items in Inbox\n    inbox = account.inbox\n    print(f\"\\nListing up to 5 unread items in Inbox for {email}:\")\n    for item in inbox.filter(is_read=False).order_by('-datetime_received')[:5]:\n        print(f\"- Subject: {item.subject}, From: {item.sender.email_address}, Received: {item.datetime_received}\")\n\nexcept Exception as e:\n    print(f\"Could not connect or perform operation: {e}\")\n    print(\"Common issues: Incorrect credentials, firewall blocking EWS, autodiscovery failure.\")\n    print(\"If autodiscovery fails, try setting `autodiscover=False` and `ews_url` manually in Configuration.\")","lang":"python","description":"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."},"warnings":[{"fix":"Migrate authentication logic to use `exchangelib.Credentials` directly. For custom protocols, ensure `auth_type` and other parameters are correctly passed to `Protocol`.","message":"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.","severity":"breaking","affected_versions":">=5.0.0"},{"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`.","message":"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.","severity":"breaking","affected_versions":">=5.0.0"},{"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`.","message":"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.","severity":"gotcha","affected_versions":"All"},{"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()`.","message":"Fetching all items from large folders (`folder.all()`) can be very slow and consume excessive memory. EWS APIs are often paginated.","severity":"gotcha","affected_versions":"All"},{"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')`.","message":"Autodiscovery might fail in complex network environments or specific Exchange configurations. This prevents `Account` from establishing a connection.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}