ddp_utils.post_office

import ddp_utils.post_office

Send email through SMTP and inspect mailboxes through IMAP.

The module provides immutable SMTP and IMAP configuration, secure transport validation, individual and personalized bulk sending, mailbox search and flag management, MIME parsing into JSON-compatible dictionaries, and a unified EmailManager facade. EmailSender remains an alias of EmailNotifier.

Examples

Configure sending and mailbox access independently:

sender = EmailNotifier(config=SMTPConfig.from_env())
mailbox = MailBox(config=IMAPConfig.from_env())
exception ddp_utils.post_office.EmailError

Bases: RuntimeError

Base email module error.

Examples

Catch every domain-specific mail failure at one boundary:

try:
    manager.verify_connection()
except EmailError as error:
    report(error)
exception ddp_utils.post_office.EmailConfigError

Bases: EmailError

Raised when email configuration is invalid.

Examples

Signal missing or insecure configuration:

raise EmailConfigError("SMTP_SERVER is required")
exception ddp_utils.post_office.EmailConnectionError

Bases: EmailError

Raised when SMTP/IMAP connection fails.

Examples

Handle unavailable mail infrastructure separately:

except EmailConnectionError:
    schedule_retry()
exception ddp_utils.post_office.EmailSendError

Bases: EmailError

Raised when SMTP send operation fails.

Examples

Request exception-based failure handling from send:

sender.send("ops@example.com", "Alert", "Failed", raise_on_error=True)
exception ddp_utils.post_office.EmailFetchError

Bases: EmailError

Raised when IMAP fetch operation fails.

Examples

Catch malformed or missing fetched messages:

except EmailFetchError as error:
    quarantine(uid, error)
exception ddp_utils.post_office.InsecureMailTransportWarning

Bases: UserWarning

Warn that mail transport or certificate verification is insecure.

Examples

Promote insecure transport warnings to errors in tests:

warnings.simplefilter("error", InsecureMailTransportWarning)
class ddp_utils.post_office.SMTPConfig(smtp_server: str, smtp_port: int = 587, username: str | None = None, password: str | None = None, use_tls: bool = True, use_ssl: bool = False, timeout: int = 30, debug: bool = False, ssl_verify: bool = True, tls_ca_file: str | None = None, allow_insecure_tls: bool = False)

Bases: object

SMTP configuration.

Parameters

Name

Type

Description

smtp_server

str

SMTP server host, for example smtp.gmail.com.

smtp_port

int

SMTP server port. Usually 587 for STARTTLS, 465 for SMTP over SSL.

username

str | None

SMTP username.

password

str | None

SMTP password or app password.

use_tls

bool

Enable STARTTLS. Usually True for port 587.

use_ssl

bool

Use SMTP_SSL. Usually True for port 465. If use_ssl=True, STARTTLS is not used.

ssl_verify

bool

Verify the SMTP TLS certificate and hostname.

tls_ca_file

str | None

Optional custom CA/certificate bundle.

allow_insecure_tls

bool

Explicitly allow plaintext SMTP or disabled certificate checks.

timeout

int

SMTP timeout in seconds.

debug

bool

Enable debug logging.

Examples

Configure verified STARTTLS explicitly:

config = SMTPConfig(
    "smtp.example.com", username="bot", password="secret"
)
classmethod from_env() → SMTPConfig

Create SMTPConfig from environment variables.

Returns

Type

Description

SMTPConfig

Configuration populated from SMTP_* variables and defaults.

Raises

Exception

Description

ValueError

A numeric environment value cannot be parsed.

Examples

Load process-level SMTP configuration:

config = SMTPConfig.from_env()
class ddp_utils.post_office.IMAPConfig(imap_server: str, imap_port: int = 993, username: str | None = None, password: str | None = None, mailbox: str = 'INBOX', use_ssl: bool = True, ssl_verify: bool = True, timeout: int = 30, debug: bool = False, allow_insecure_tls: bool = False)

Bases: object

IMAP configuration.

Parameters

Name

Type

Description

imap_server

str

IMAP server host, for example imap.gmail.com.

imap_port

int

IMAP server port. Usually 993 for SSL.

username

str | None

IMAP username.

password

str | None

IMAP password or app password.

mailbox

str

Default mailbox/folder. Usually INBOX.

use_ssl

bool

Use IMAP over SSL.

ssl_verify

bool

Verify SSL certificate.

allow_insecure_tls

bool

Explicitly allow plaintext IMAP or disabled certificate checks.

timeout

int

IMAP timeout in seconds.

debug

bool

Enable debug logging.

Examples

Configure a verified IMAPS mailbox:

config = IMAPConfig(
    "imap.example.com", username="bot", password="secret"
)
classmethod from_env() → IMAPConfig

Create IMAPConfig from environment variables.

Returns

Type

Description

IMAPConfig

Configuration populated from IMAP_* variables and fallbacks.

Raises

Exception

Description

ValueError

A numeric environment value cannot be parsed.

Examples

Load process-level IMAP configuration:

config = IMAPConfig.from_env()
class ddp_utils.post_office.EmailNotifier(smtp_server: str | None = None, smtp_port: int | None = None, username: str | None = None, password: str | None = None, use_tls: bool = True, timeout: int = 30, debug: bool = False, use_ssl: bool = False, config: SMTPConfig | None = None, *, ssl_verify: bool = True, tls_ca_file: str | None = None, allow_insecure_tls: bool = False)

Bases: object

SMTP email sender.

This class preserves the old public API:

  • verify_connection()

  • send()

  • send_bulk()

It can be configured either explicitly or via environment variables:

SMTP_SERVER SMTP_PORT SMTP_USERNAME SMTP_PASSWORD SMTP_USE_TLS SMTP_USE_SSL SMTP_TIMEOUT SMTP_DEBUG

Examples

Create a sender from immutable configuration:

sender = EmailNotifier(config=SMTPConfig.from_env())

Resolve SMTP settings and enforce an explicit transport policy.

A supplied config provides every effective setting. Otherwise, explicit arguments fall back to SMTP_* environment variables.

Parameters

Name

Type

Description

smtp_server

Optional[str]

SMTP server hostname.

smtp_port

Optional[int]

SMTP server port.

username

Optional[str]

SMTP authentication username.

password

Optional[str]

SMTP password or application password.

use_tls

bool

Whether to negotiate STARTTLS.

timeout

int

Connection timeout in seconds.

debug

bool

Whether to emit SMTP diagnostic records.

use_ssl

bool

Whether to use implicit SMTPS instead of STARTTLS.

config

SMTPConfig | None

Complete immutable configuration overriding other fields.

ssl_verify

bool

Whether to verify the server certificate and hostname.

tls_ca_file

str | None

Optional CA bundle used for certificate validation.

allow_insecure_tls

bool

Explicit opt-in to plaintext transport or disabled certificate verification.

Raises

Exception

Description

EmailConfigError

Required settings are missing or insecure transport was selected without explicit opt-in.

Examples

Initialize a sender from a complete configuration:

sender = EmailNotifier(config=SMTPConfig.from_env())
verify_connection(raise_on_error: bool = True) → bool

Verify SMTP connectivity and credentials without sending an email.

Parameters

Name

Type

Description

raise_on_error

bool

If True, raise RuntimeError on failure. If False, return False on failure.

Returns

Type

Description

bool

True if SMTP server is reachable and login succeeds.

Raises

Exception

Description

EmailConnectionError

Verification fails and raise_on_error is true.

Examples

Probe credentials without aborting the caller:

available = sender.verify_connection(raise_on_error=False)
send(to_addrs: str | List[str], subject: str, body: str, from_addr: str | None = None, body_type: Literal['plain', 'html'] = 'plain', attachments: List[str | Path] | None = None, cc: List[str] | None = None, bcc: List[str] | None = None, raise_on_error: bool = False) → bool

Send one email.

Parameters

Name

Type

Description

to_addrs

str | List[str]

Recipient email or list of recipient emails.

subject

str

Email subject.

body

str

Email body.

from_addr

str | None

Sender address. If omitted, username is used.

body_type

Literal['plain', 'html']

“plain” or “html”.

attachments

List[str | Path] | None

Optional list of file paths.

cc

List[str] | None

Optional CC recipients.

bcc

List[str] | None

Optional BCC recipients. BCC recipients are used in SMTP envelope but are not written into message headers.

raise_on_error

bool

If True, raise EmailSendError on failure. If False, return False on failure.

Returns

Type

Description

bool

True on success, False on failure.

Raises

Exception

Description

EmailSendError

Sending fails and raise_on_error is true.

Examples

Send one HTML message with a copied recipient:

sent = sender.send(
    "user@example.com",
    "Status",
    "<b>Ready</b>",
    body_type="html",
    cc=["audit@example.com"],
)
send_bulk(recipients: List[str | List[str] | tuple], subject: str, body_template: str, from_addr: str | None = None, body_type: Literal['plain', 'html'] = 'plain', attachments: List[str | Path] | None = None, delay: float = 1.0, **kwargs: Any) → dict[str, Any]

Send personalized bulk emails.

Parameters

Name

Type

Description

recipients

List[str | List[str] | tuple]

Recipient specifications. Each item may be an address string or a two-item list or tuple containing an address and name.

subject

str

Subject template supporting .format(name=..., **kwargs).

body_template

str

Body template supporting .format(name=..., **kwargs).

from_addr

str | None

Sender address.

body_type

Literal['plain', 'html']

"plain" or "html".

attachments

List[str | Path] | None

Shared attachment list.

delay

float

Delay between emails in seconds.

kwargs

Any

Extra template variables.

Returns

Type

Description

dict[str, Any]

Result dictionary with integer "success" and "failed" counts and an "errors" list.

Examples

Personalize a named recipient list without delay:

result = sender.send_bulk(
    [("user@example.com", "Alex")],
    "Hello {name}",
    "Your report is ready, {name}.",
    delay=0,
)
ddp_utils.post_office.EmailSender

alias of EmailNotifier

class ddp_utils.post_office.MailBox(imap_server: str | None = None, imap_port: int | None = None, username: str | None = None, password: str | None = None, mailbox: str | None = None, use_ssl: bool = True, ssl_verify: bool = True, timeout: int = 30, debug: bool = False, config: IMAPConfig | None = None, *, allow_insecure_tls: bool = False)

Bases: object

IMAP mailbox reader.

Environment variables:

IMAP_SERVER IMAP_PORT IMAP_USERNAME IMAP_PASSWORD IMAP_MAILBOX IMAP_USE_SSL IMAP_SSL_VERIFY IMAP_TIMEOUT IMAP_DEBUG

If IMAP_USERNAME or IMAP_PASSWORD are not set, class can fallback to:

SMTP_USERNAME SMTP_PASSWORD

Examples

Open the configured mailbox for one managed operation:

with MailBox(config=IMAPConfig.from_env()) as mailbox:
    messages = mailbox.fetch_recent(limit=5, unread_only=True)

Resolve IMAP settings and enforce an explicit transport policy.

A supplied config provides every effective setting. Otherwise, explicit arguments fall back to IMAP_* variables, with SMTP credentials used only as username and password fallbacks.

Parameters

Name

Type

Description

imap_server

Optional[str]

IMAP server hostname.

imap_port

Optional[int]

IMAP server port.

username

Optional[str]

IMAP authentication username.

password

Optional[str]

IMAP password or application password.

mailbox

Optional[str]

Default mailbox selected by managed operations.

use_ssl

bool

Whether to use implicit IMAPS.

ssl_verify

bool

Whether to verify the server certificate and hostname.

timeout

int

Connection timeout in seconds.

debug

bool

Whether to emit IMAP diagnostic records.

config

IMAPConfig | None

Complete immutable configuration overriding other fields.

allow_insecure_tls

bool

Explicit opt-in to plaintext transport or disabled certificate verification.

Raises

Exception

Description

EmailConfigError

Required settings are missing or insecure transport was selected without explicit opt-in.

Examples

Initialize mailbox access from immutable configuration:

mailbox = MailBox(config=IMAPConfig.from_env())
property is_connected: bool

Return whether an IMAP client is currently attached.

Returns

True after connection and before close().

Examples

Avoid reconnecting an already open mailbox:

if not mailbox.is_connected:
    mailbox.connect()
property selected_mailbox: str | None

Return the last successfully selected mailbox name.

Returns

Selected folder name, or None before selection or after close.

Examples

Inspect the current search scope:

current_folder = mailbox.selected_mailbox
connect() → None

Connect and login to IMAP server.

Warns

InsecureMailTransportWarning – Transport or verification is insecure and the warning has not already been emitted.

Raises

Exception

Description

EmailConnectionError

Connection or authentication fails.

Examples

Connect explicitly before several mailbox operations:

mailbox.connect()
close() → None

Close the selected mailbox and best-effort log out.

Examples

Release an explicitly opened connection:

mailbox.close()
verify_connection(raise_on_error: bool = True) → bool

Verify IMAP connectivity and credentials.

Parameters

Name

Type

Description

raise_on_error

bool

If True, raise EmailConnectionError on failure. If False, return False.

Returns

Type

Description

bool

True if connection/login/select mailbox succeeded.

Raises

Exception

Description

EmailConnectionError

Verification fails and raise_on_error is true.

Examples

Probe mailbox availability without raising:

available = mailbox.verify_connection(raise_on_error=False)
list_mailboxes() → list[str]

Return available IMAP mailboxes/folders.

Returns

Type

Description

list[str]

Decoded mailbox names in server response order.

Raises

Exception

Description

EmailConnectionError

The client is not connected.

EmailError

The IMAP LIST command fails.

Examples

Discover folders after connecting:

folders = mailbox.list_mailboxes()
select_mailbox(mailbox: str = 'INBOX', readonly: bool = False) → int

Select mailbox/folder.

Parameters

Name

Type

Description

mailbox

str

Mailbox name.

readonly

bool

If True, IMAP does not change message flags.

Returns

Type

Description

int

Number of messages in mailbox.

Raises

Exception

Description

EmailConnectionError

The client is not connected.

EmailError

The server rejects mailbox selection.

Examples

Select a read-only archive folder:

count = mailbox.select_mailbox("Archive", readonly=True)
search(flag: Literal['ALL', 'UNSEEN', 'SEEN', 'ANSWERED', 'UNANSWERED', 'FLAGGED', 'UNFLAGGED', 'DELETED', 'UNDELETED'] = 'ALL', *, from_email: str | None = None, subject_contains: str | None = None, since: str | None = None, before: str | None = None) → list[str]

Search emails and return IMAP UIDs.

Parameters

Name

Type

Description

flag

Literal['ALL', 'UNSEEN', 'SEEN', 'ANSWERED', 'UNANSWERED', 'FLAGGED', 'UNFLAGGED', 'DELETED', 'UNDELETED']

IMAP search flag.

from_email

str | None

Optional sender filter.

subject_contains

str | None

Optional subject filter.

since

str | None

Optional IMAP date, example “01-Jan-2026”.

before

str | None

Optional IMAP date, example “30-Jun-2026”.

Returns

Type

Description

list[str]

List of UID strings, oldest first.

Raises

Exception

Description

EmailConnectionError

The client is not connected.

EmailError

The IMAP search command fails.

Examples

Find unread messages from one sender:

uids = mailbox.search("UNSEEN", from_email="alerts@example.com")
fetch_email(uid: str, *, mark_seen: bool = False, include_attachments_data: bool = False, max_attachment_bytes: int = 5000000) → dict[str, Any]

Fetch one email by UID.

Parameters

Name

Type

Description

uid

str

IMAP UID.

mark_seen

bool

If True, email may be marked as read. If False, BODY.PEEK is used.

include_attachments_data

bool

If True, include attachment payload as latin1 string. Usually keep False and save attachments separately.

max_attachment_bytes

int

Max attachment size included into JSON object.

Returns

Type

Description

dict[str, Any]

JSON-compatible dict.

Raises

Exception

Description

EmailConnectionError

The client is not connected.

EmailFetchError

Fetching yields an error or no message payload.

Examples

Fetch one message without changing its seen flag:

message = mailbox.fetch_email("42", mark_seen=False)
fetch_recent(*, limit: int = 10, unread_only: bool = False, newest_first: bool = True, mark_seen: bool = False) → list[dict[str, Any]]

Fetch recent emails.

Parameters

Name

Type

Description

limit

int

Max number of emails.

unread_only

bool

If True, fetch only unread emails.

newest_first

bool

If True, newest emails are returned first.

mark_seen

bool

If True, fetched emails may become read.

Returns

Type

Description

list[dict[str, Any]]

List of structured email dicts.

Raises

Exception

Description

EmailError

Searching or fetching a selected message fails.

Examples

Read the five newest unread messages:

messages = mailbox.fetch_recent(limit=5, unread_only=True)
get_unseen_count() → int

Return count of unseen emails in selected mailbox.

Returns

Type

Description

int

Number of UIDs returned by an UNSEEN search.

Examples

Report unread work without fetching message bodies:

unread = mailbox.get_unseen_count()
mark_seen(uid: str) → None

Mark email as seen/read.

Parameters

Name

Type

Description

uid

str

IMAP message UID.

Examples

Mark a processed message as read:

mailbox.mark_seen("42")
mark_unseen(uid: str) → None

Mark email as unseen/unread.

Parameters

Name

Type

Description

uid

str

IMAP message UID.

Examples

Return a deferred message to the unread queue:

mailbox.mark_unseen("42")
delete(uid: str, *, expunge: bool = False) → None

Mark email as deleted.

Parameters

Name

Type

Description

uid

str

IMAP UID.

expunge

bool

If True, permanently remove deleted messages.

Raises

Exception

Description

EmailError

If the IMAP expunge fails.

Examples

Mark a message deleted without immediately expunging it:

mailbox.delete("42", expunge=False)
to_json_string(email_obj: dict[str, Any], *, indent: int = 2) → str

Convert email object to JSON string.

Parameters

Name

Type

Description

email_obj

dict[str, Any]

JSON-compatible message object returned by this class.

indent

int

Pretty-print indentation width.

Returns

Type

Description

str

Unicode-preserving JSON text.

Examples

Serialize a fetched message for storage:

text = mailbox.to_json_string(message, indent=2)
class ddp_utils.post_office.EmailManager(smtp_config: SMTPConfig | None = None, imap_config: IMAPConfig | None = None, *, smtp_server: str | None = None, smtp_port: int | None = None, imap_server: str | None = None, imap_port: int | None = None, username: str | None = None, password: str | None = None, smtp_username: str | None = None, smtp_password: str | None = None, imap_username: str | None = None, imap_password: str | None = None, mailbox: str = 'INBOX', smtp_use_tls: bool = True, smtp_use_ssl: bool = False, smtp_ssl_verify: bool = True, smtp_tls_ca_file: str | None = None, smtp_allow_insecure_tls: bool = False, imap_use_ssl: bool = True, imap_ssl_verify: bool = True, imap_allow_insecure_tls: bool = False, timeout: int = 30, debug: bool = False, enable_sender: bool = True, enable_mailbox: bool = True)

Bases: object

Expose SMTP sending and IMAP mailbox operations through one object.

Either side can be disabled independently. The manager owns an EmailNotifier in sender and a MailBox in mailbox and forwards the common operations to those components.

Examples

Send a message and read recent inbox entries through one manager:

with EmailManager(
    smtp_config=smtp_config,
    imap_config=imap_config,
) as manager:
    manager.send("ops@example.com", "Run complete", "Success")
    recent = manager.fetch_recent(limit=5)

Initialize the enabled SMTP and IMAP components.

Parameters

Name

Type

Description

smtp_config

SMTPConfig | None

Complete SMTP configuration. Individual SMTP arguments are used when this is omitted.

imap_config

IMAPConfig | None

Complete IMAP configuration. Individual IMAP arguments are used when this is omitted.

smtp_server

Optional[str]

SMTP host used without smtp_config.

smtp_port

Optional[int]

SMTP port used without smtp_config.

imap_server

Optional[str]

IMAP host used without imap_config.

imap_port

Optional[int]

IMAP port used without imap_config.

username

Optional[str]

Shared credential fallback for both protocols.

password

Optional[str]

Shared password fallback for both protocols.

smtp_username

Optional[str]

SMTP-specific username overriding username.

smtp_password

Optional[str]

SMTP-specific password overriding password.

imap_username

Optional[str]

IMAP-specific username overriding username.

imap_password

Optional[str]

IMAP-specific password overriding password.

mailbox

str

Default IMAP mailbox name.

smtp_use_tls

bool

Upgrade SMTP with STARTTLS.

smtp_use_ssl

bool

Open SMTP over implicit TLS.

smtp_ssl_verify

bool

Verify SMTP certificates and hostnames.

smtp_tls_ca_file

str | None

Optional SMTP CA bundle path.

smtp_allow_insecure_tls

bool

Explicitly permit disabled SMTP validation.

imap_use_ssl

bool

Open IMAP over implicit TLS.

imap_ssl_verify

bool

Verify IMAP certificates and hostnames.

imap_allow_insecure_tls

bool

Explicitly permit disabled IMAP validation.

timeout

int

Network timeout in seconds for both protocols.

debug

bool

Enable protocol-library diagnostic output.

enable_sender

bool

Create the SMTP component when true.

enable_mailbox

bool

Create the IMAP component when true.

Raises

Exception

Description

EmailConfigError

Required configuration is missing or an insecure TLS combination was not explicitly allowed.

Examples

Create an SMTP-only manager with explicit configuration:

manager = EmailManager(
    smtp_config=smtp_config,
    enable_mailbox=False,
)
classmethod from_env(*, enable_sender: bool = True, enable_mailbox: bool = True) → EmailManager

Create enabled email components from environment variables.

Parameters

Name

Type

Description

enable_sender

bool

Load SMTP configuration and create a sender.

enable_mailbox

bool

Load IMAP configuration and create a mailbox.

Returns

Type

Description

EmailManager

A configured manager whose disabled components are None.

Raises

Exception

Description

EmailConfigError

An enabled component lacks required environment variables or violates the transport security policy.

Examples

Load an IMAP-only manager from IMAP_* variables:

manager = EmailManager.from_env(
    enable_sender=False,
    enable_mailbox=True,
)
verify_connection(raise_on_error: bool = True) → dict[str, bool]

Verify enabled SMTP and IMAP connections.

Parameters

Name

Type

Description

raise_on_error

bool

Re-raise the first protocol error when true; return false for that component when false.

Returns

Type

Description

dict[str, bool]

A dictionary with boolean smtp and imap results. Disabled components remain false.

Raises

Exception

Description

EmailConnectionError

A connection check fails and raise_on_error is true.

Examples

Probe both enabled services without raising:

status = manager.verify_connection(raise_on_error=False)
send(*args: Any, **kwargs: Any) → bool

Send one message through the enabled SMTP component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by EmailNotifier.send().

**kwargs

Any

Keyword arguments accepted by EmailNotifier.send().

Returns

Type

Description

bool

True after the SMTP server accepts the message.

Raises

Exception

Description

EmailConfigError

SMTP support is disabled.

EmailSendError

Message construction or delivery fails.

Examples

Send a plain-text notification:

manager.send("ops@example.com", "Status", "Complete")
send_bulk(*args: Any, **kwargs: Any) → dict[str, Any]

Send multiple messages through the enabled SMTP component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by EmailNotifier.send_bulk().

**kwargs

Any

Keyword arguments accepted by EmailNotifier.send_bulk().

Returns

Type

Description

dict[str, Any]

Bulk-delivery summary from EmailNotifier.send_bulk().

Raises

Exception

Description

EmailConfigError

SMTP support is disabled.

EmailSendError

Delivery fails under the selected error policy.

Examples

Deliver a prepared batch:

summary = manager.send_bulk(messages, continue_on_error=True)
list_mailboxes() → list[str]

List mailbox names through the enabled IMAP component.

Returns

Type

Description

list[str]

Mailbox names reported by the IMAP server.

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailConnectionError

No connection is available.

EmailError

The server rejects the LIST command.

Examples

Inspect available folders:

names = manager.list_mailboxes()
select_mailbox(*args: Any, **kwargs: Any) → int

Select an IMAP mailbox through the enabled component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by MailBox.select_mailbox().

**kwargs

Any

Keyword arguments accepted by MailBox.select_mailbox().

Returns

Type

Description

int

Number of messages reported for the selected mailbox.

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailError

The server rejects the selection.

Examples

Select the archive read-only:

count = manager.select_mailbox("Archive", readonly=True)
search(*args: Any, **kwargs: Any) → list[str]

Search the selected mailbox through the enabled IMAP component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by MailBox.search().

**kwargs

Any

Keyword arguments accepted by MailBox.search().

Returns

Type

Description

list[str]

Matching message UIDs.

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailError

The server rejects the search.

Examples

Find unread messages:

uids = manager.search("UNSEEN")
fetch_email(*args: Any, **kwargs: Any) → dict[str, Any]

Fetch one parsed message through the enabled IMAP component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by MailBox.fetch_email().

**kwargs

Any

Keyword arguments accepted by MailBox.fetch_email().

Returns

Type

Description

dict[str, Any]

JSON-compatible message data.

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailFetchError

The message cannot be fetched or parsed.

Examples

Fetch a message without attachment bytes:

message = manager.fetch_email("42", include_attachments_data=False)
fetch_recent(*args: Any, **kwargs: Any) → list[dict[str, Any]]

Fetch recent parsed messages through the enabled IMAP component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by MailBox.fetch_recent().

**kwargs

Any

Keyword arguments accepted by MailBox.fetch_recent().

Returns

Type

Description

list[dict[str, Any]]

Parsed messages ordered according to the mailbox implementation.

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailFetchError

A requested message cannot be fetched or parsed.

Examples

Read the ten newest messages:

messages = manager.fetch_recent(limit=10)
get_unseen_count() → int

Count unseen messages through the enabled IMAP component.

Returns

Type

Description

int

Number of UIDs matching UNSEEN.

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailError

The IMAP search fails.

Examples

Check whether unread work exists:

pending = manager.get_unseen_count()
mark_seen(*args: Any, **kwargs: Any) → None

Add the seen flag through the enabled IMAP component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by MailBox.mark_seen().

**kwargs

Any

Keyword arguments accepted by MailBox.mark_seen().

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailError

The server rejects the flag update.

Examples

Mark a processed message as read:

manager.mark_seen("42")
mark_unseen(*args: Any, **kwargs: Any) → None

Remove the seen flag through the enabled IMAP component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by MailBox.mark_unseen().

**kwargs

Any

Keyword arguments accepted by MailBox.mark_unseen().

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailError

The server rejects the flag update.

Examples

Return a message to the unread queue:

manager.mark_unseen("42")
delete(*args: Any, **kwargs: Any) → None

Mark a message deleted through the enabled IMAP component.

Parameters

Name

Type

Description

*args

Any

Positional arguments accepted by MailBox.delete().

**kwargs

Any

Keyword arguments accepted by MailBox.delete().

Raises

Exception

Description

EmailConfigError

IMAP support is disabled.

EmailError

Flagging or optional expunging fails.

Examples

Delete and immediately expunge a message:

manager.delete("42", expunge=True)