Skip to main content

Python Sage IMAP

PyPI version Python License: MIT codecov Documentation

Production-oriented IMAP for Python 3.10+ — UID-first mailbox operations, CONDSTORE sync, IDLE, OAuth2, SPECIAL-USE folders, and an optional async API (sage_imap.aio).

Current release: 2.0.0 — sync API on stdlib imaplib; async via optional [async] extra (aioimaplib).

Why this library?

Python Sage IMAP targets applications that need reliable email access beyond thin imaplib wrappers:

  • UID-first search, fetch, move, and flag operations via IMAPMailboxUIDService and IMAPSession
  • Streaming fetch with iter_uid_fetch / iter_messages and ParseMode (headers-only, minimal, full, raw)
  • Incremental sync with CONDSTORE (MailboxSyncState, CHANGEDSINCE)
  • IDLE for push-style mailbox notifications
  • OAuth2 with refresh (OAuth2Config, ensure_access_token)
  • Resilience — retries, connection pooling (use_pool=True), metrics, health checks
  • Async parity — AsyncIMAPSession under sage_imap.aio (install [async])

Installation

pip install python-sage-imap

Async support:

pip install python-sage-imap[async]

Requirements: Python 3.10+, network access to an IMAP server (TLS recommended).

Development

git clone https://github.com/sageteamorg/python-sage-imap.git
cd python-sage-imap
poetry install
poetry install -E async   # optional, for sage_imap.aio tests
poetry run pytest -m "not integration"

Integration tests against a Mailcow-compatible stack:

make integration-up
make integration-test
make integration-down

Set IMAP_HOST, IMAP_USER, IMAP_PASSWORD, and optionally IMAP_PORT. See docker/mailcow/README.md.

Quick start (sync)

Use IMAPSession as the primary entry point:

from sage_imap import IMAPSession, IMAPSearchCriteria, SpecialUse

with IMAPSession("imap.example.com", "user@example.com", "app-password") as session:
    session.select("INBOX")
    result = session.search(IMAPSearchCriteria.UNSEEN)
    trash = session.special_folder(SpecialUse.TRASH)
    for msg in session.iter_messages(result.to_uid_message_set(), batch_size=50):
        print(msg.uid, msg.subject)

More: docs/SESSION.md · Read the Docs

Quick start (async)

import asyncio
from sage_imap.aio import AsyncIMAPSession
from sage_imap.helpers.search import IMAPSearchCriteria

async def main():
    async with AsyncIMAPSession("imap.example.com", "user@example.com", "secret") as session:
        await session.select("INBOX")
        result = await session.search(IMAPSearchCriteria.UNSEEN)
        async for msg in session.iter_messages(result.to_uid_message_set()):
            print(msg.subject)

asyncio.run(main())

See docs/ASYNC.md and examples/09_async_session.py.

Sync vs async

Topic Sync Async
Import from sage_imap import IMAPSession from sage_imap.aio import AsyncIMAPSession
Transport imaplib + threading.RLock aioimaplib + asyncio.Lock
Install pip install python-sage-imap pip install python-sage-imap[async]
OAuth refresh stdlib (urllib) httpx (or thread fallback)

Async is not re-exported from top-level sage_imap (by design). See docs/MIGRATION_v2.md when upgrading from 1.x.

Lower-level API

Services remain available for fine-grained control:

from sage_imap import IMAPClient, IMAPMailboxUIDService, IMAPSearchCriteria

with IMAPClient("imap.example.com", "user@example.com", "secret") as client:
    caps = client.transport.get_capabilities()
    mailbox = IMAPMailboxUIDService(client)
    mailbox.select("INBOX")
    result = mailbox.uid_search(IMAPSearchCriteria.ALL)
    for msg in mailbox.iter_uid_fetch(result.to_uid_message_set()):
        print(msg.subject)

IMAPClient delegates raw imaplib methods (e.g. list, select) when connected; prefer UID services for message operations.

Examples

Runnable scripts live under examples/. Configure credentials via environment variables:

export IMAP_HOST=imap.example.com
export IMAP_USER=user@example.com
export IMAP_PASSWORD=secret
poetry run python examples/01_basic_client_usage.py
Script Topic
01_basic_client_usage.py Client, pooling, metrics
02_connection_pooling_example.py use_pool=True
03_retry_and_resilience_example.py Retries and recovery
04_monitoring_and_metrics_example.py ConnectionMetrics
05_advanced_client_features.py OAuth, TLS, health
06_mailbox_operations_example.py Mailbox CRUD
07_advanced_mailbox_features.py Upload, bulk ops
08_mailbox_uid_operations.py UID search/fetch
09_async_session.py Async session

See examples/README.md.

Configuration

from sage_imap import ConnectionConfig, IMAPSession, build_ssl_context

config = ConnectionConfig(
    host="imap.example.com",
    username="user@example.com",
    password="secret",
    port=993,
    use_ssl=True,
    timeout=30.0,
    max_retries=5,
    retry_delay=2.0,
    enable_monitoring=True,
    enable_background_health=False,
)

with IMAPSession.from_config(config) as session:
    session.select("INBOX")

Documentation

Testing

poetry run pytest -m "not integration"
poetry run pytest tests/aio -m "not integration"   # requires -E async
poetry run pytest --cov=sage_imap --cov-report=html

Contributing

See CONTRIBUTING.md and SECURITY.md.

make setup-dev
make test
make lint

License

MIT — see LICENSE.

Support

Metadata

Release files for python-sage-imap 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-sage-imap 2.0.0
File Size Uploaded
python_sage_imap-2.0.0.tar.gz 305.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for python-sage-imap 2.0.0
File Interpreter ABI Platform
python_sage_imap-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 657.9 kB

Release files / python_sage_imap-2.0.0.tar.gz

Download URL python_sage_imap-2.0.0.tar.gz
Size 305.0 kB
Tags Source
SHA-256 checksum
How to use checksums
ee5975f66533641eb6fc6405688451fd0af4dace1c70b20f0b160976fef65136
BLAKE2b-256 checksum
How to use checksums
70346d5ecdba5aa5238b7027662ea1910ed9c36ae985d445104b69b6aaf519a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.0.1 CPython/3.12.4 Windows/11

Release files / python_sage_imap-2.0.0-py3-none-any.whl

Download URL python_sage_imap-2.0.0-py3-none-any.whl
Size 352.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a60c9ff15f727dfd3599af974207e6250552bc0d130eb83011ed974e2a955d59
BLAKE2b-256 checksum
How to use checksums
f26db6da4b22ecd4fb53c752286c4c05e33f36d03dbbdc60ed33553a7dcfa735
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.0.1 CPython/3.12.4 Windows/11

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files

0.4.8

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page