duck.utils.email

A reusable utility module for sending emails via SMTP, suitable for integration in any Python project or library. Provides a generic Email class for any SMTP server and a Gmail subclass for Gmail-specific settings, with both synchronous and asynchronous implementations.

… note::

You should load sensitive credentials (like SMTP usernames and passwords) securely, for example using environment variables or a .env file: from dotenv import load_dotenv; load_dotenv() Or by passing them directly as arguments to class constructors.

Author: Brian Musakwa digreatbrian@gmail.com

Submodules

Package Contents

Classes

Email

Compose and send emails via any SMTP server (sync and async).

Gmail

Compose and send emails specifically via Gmail’s SMTP server.

Spacemail

Compose and send emails specifically via Spacemail’s SMTP server.

API

class duck.utils.email.Email(smtp_host: str, smtp_port: int, username: str, password: str, from_addr: str, name: str, to: str, subject: str, body: str, recipients: Optional[List[str]] = None, use_bcc: bool = True, use_ssl: bool = True, reply_to: Optional[str] = None)[source]

Compose and send emails via any SMTP server (sync and async).

This class provides a general interface to create an email and send it using any SMTP server. It supports sending to a single recipient and optionally multiple recipients via CC or BCC.

Variables:
  • smtp_host – SMTP server hostname (e.g., “smtp.gmail.com”).

  • smtp_port – SMTP server port (e.g., 465 for SSL).

  • username – SMTP server login username (usually the sender’s email).

  • password – SMTP server login password or app password.

  • use_ssl – Whether to use SSL for SMTP (default True).

  • from_addr – The sender’s email address.

  • name – The sender’s display name.

  • to – The main recipient’s email address.

  • subject – The subject of the email.

  • body – The HTML content of the email.

  • recipients – Additional recipient emails for CC/BCC.

  • use_bcc – If True, recipients are BCCed; otherwise, they are CCed.

  • is_sent – True if the email was sent successfully.

… rubric:: Example

email = Email( smtp_host=“smtp.mailgun.org”, smtp_port=465, username=”your@mail.com”, password=“yourpassword”, from_addr=”your@mail.com”, name=“Your Name”, to=”recipient@example.com”, subject=“Hello from Mailgun”, body=“Welcome!”, ) email.send()

or for async:

await email.async_send()

Initialization

Initialize a generic Email instance.

Parameters:
  • smtp_host – SMTP server host.

  • smtp_port – SMTP server port.

  • username – SMTP login username (email address).

  • password – SMTP login password or app password.

  • from_addr – Sender’s email address.

  • name – Sender’s display name.

  • to – Main recipient’s email address.

  • subject – Subject of the email.

  • body – HTML content of the email.

  • recipients – List of additional recipient emails for CC/BCC (optional).

  • use_bcc – If True, use BCC for recipients; otherwise, use CC.

  • use_ssl – Whether to use SSL for SMTP (default True).

  • reply_to – An email for users to reply to when they hit ‘Reply’. Defaults to None, uses default from_addr.

__repr__()[source]
__str__()[source]
_build_message() Tuple[email.mime.multipart.MIMEMultipart, List[str]][source]

Build the MIME email message and return (msg, all_recipients).

Returns:

(MIMEMultipart message, list of all recipient addresses)

Return type:

Tuple

async async_send() None[source]

Send the composed email using the specified SMTP server (asynchronously).

Requires: aiosmtplib (pip install aiosmtplib)

Raises:
  • ImportError – If aiosmtplib is not installed.

  • Exception – If sending fails due to authentication or network errors.

send() None[source]

Send the composed email using the specified SMTP server (synchronously).

Raises:

Exception – If sending fails due to authentication or network errors.

class duck.utils.email.Gmail(username: str, password: str, from_addr: str, name: str, to: str, subject: str, body: str, recipients: Optional[List[str]] = None, use_bcc: bool = True, use_ssl: bool = True, reply_to: Optional[str] = None)[source]

Bases: duck.utils.email.Email

Compose and send emails specifically via Gmail’s SMTP server.

This is a convenience subclass of Email that pre-fills Gmail’s SMTP configuration. You must still provide your Gmail address and app password.

Example:

gmail = Gmail(
    username="your@gmail.com",
    password="your_app_password",
    from_addr="your@gmail.com",
    name="Your Name",
    to="recipient@example.com",
    subject="Hello from Gmail",
    body="<b>Welcome!</b>",
)

# Synchronous sending
gmail.send()

# Asynchronous sending
await gmail.async_send()

Initialization

Initialize a Gmail email instance with Gmail’s SMTP settings.

Parameters:
  • username – Gmail address.

  • password – Gmail app password.

  • from_addr – Gmail address (same as username).

  • name – Sender’s display name.

  • to – Main recipient’s email address.

  • subject – Subject of the email.

  • body – HTML content of the email.

  • recipients – List of additional recipient emails (optional).

  • use_bcc – If True, use BCC for recipients; otherwise, use CC.

  • use_ssl – Whether to use SSL for SMTP (default True).

  • reply_to – An email for users to reply to when they hit ‘Reply’. Defaults to None, uses default from_addr.

class duck.utils.email.Spacemail(username: str, password: str, from_addr: str, name: str, to: str, subject: str, body: str, recipients: Optional[List[str]] = None, use_bcc: bool = True, use_ssl: bool = True, reply_to: Optional[str] = None)[source]

Bases: duck.utils.email.Email

Compose and send emails specifically via Spacemail’s SMTP server.

This is a convenience subclass of Email that pre-fills Spacemail’s SMTP configuration. You must still provide your Spacemail address and mailbox password — Spacemail has no separate app-password/token system, so this is the same password used to log into webmail.

Example:

spacemail = Spacemail(
    username="hello@yourdomain.com",
    password="your_mailbox_password",
    from_addr="hello@yourdomain.com",
    name="Your Name",
    to="recipient@example.com",
    subject="Hello from Spacemail",
    body="<b>Welcome!</b>",
)

# Synchronous sending
spacemail.send()

# Asynchronous sending
await spacemail.async_send()

Initialization

Initialize a Spacemail email instance with Spacemail’s SMTP settings.

Parameters:
  • username – Full Spacemail address.

  • password – Spacemail mailbox password.

  • from_addr – Spacemail address (same as username).

  • name – Sender’s display name.

  • to – Main recipient’s email address.

  • subject – Subject of the email.

  • body – HTML content of the email.

  • recipients – List of additional recipient emails (optional).

  • use_bcc – If True, use BCC for recipients; otherwise, use CC.

  • use_ssl – Whether to use SSL (default True → port 465). Set False to use STARTTLS on port 587 instead.

  • reply_to – An email for users to reply to when they hit ‘Reply’. Defaults to None, uses default from_addr.