Red Mail Documentation

repository·master·Indexed 16 days ago

https://github.com/miksus/red-mail

An advanced Python email sending library designed to simplify complex emails with attachments, Jinja templates, and embedded media. It provides the EmailSender class for SMTP dispatching, a Flask-Redmail extension for web applications, and logging handlers (EmailHandler and MultiEmailHandler) for sending log records via email. Supports various SMTP connection types including STARTTLS, SMTP SSL, and LMTP.

Tokens
17.2K
Snippets
56
Records
67
Agent score
64%

What's inside redmail

  1. Overview of Red Mail features

    master

    Red Mail is an advanced email sender for Python designed to make complex email tasks trivial. Key capabilities include:

    • Rich Content: Easily embed images, plots, and tables directly into the email body.
    • Attachments: Attach documents to your emails.
    • Templating: Built-in support for Jinja templates and reusable HTML templates.
    • Pre-configured Providers: Easy setup for Gmail and Outlook.
    • Advanced Routing: Support for cc and bcc recipients.
    • Extensibility: Includes a logging handler and a Flask extension.
    • Protocol Flexibility: Ability to configure specific SMTP settings.
  2. Override SMTP settings for custom providers

    master

    If you are using a custom SMTP server or need to change the default protocol/port for a provider, you can override the attributes of the sender instance.

    By default, Red Mail uses STARTTLS. If your provider requires a different protocol or port, you can manually set:

    • sender.port: The port number.
    • sender.cls_smtp: The SMTP class/protocol configuration.
  3. Understand Red Mail's MIME email structure

    master

    Red Mail structures emails using standard MIME parts. Understanding this hierarchy is useful for debugging rendering issues with email providers or writing unit tests. The structure changes based on the content provided:

    • Empty Email: Contains only headers, no MIME parts.
    • Text Body: Uses text/plain.
    • HTML Body: Uses multipart/mixed containing a multipart/alternative part with text/html.
    • HTML Body with Inline JPG: Uses multipart/mixed -> multipart/alternative -> multipart/related containing text/html and image/jpg.
    • Email with Attachment: Uses multipart/mixed containing an application/octet-stream part.
    • Full Email (Text, HTML, Inline Image, and Attachment): Uses a complex hierarchy:
      • multipart/mixed
        • multipart/alternative
          • text/plain
          • multipart/related (text/html and image/jpg)
        • application/octet-stream (the attachment)
  4. Use pre-configured provider instances

    master

    Red Mail includes pre-configured sender instances for common email providers to simplify setup. These instances come with the correct host and port pre-set.

    ProviderSender instanceHostPort
    Gmail (Google)redmail.gmailsmtp.gmail.com587
    Outlook (Microsoft)redmail.outlooksmtp.office365.com587

    Note on Sender Identity: Many providers do not allow you to change the sender address to something different from the credentials used to log in. In such cases, providing a different sender argument to the .send() method may have no effect.

  5. Pass an EmailSender instance to a logging handler

    master

    Instead of providing individual SMTP parameters, you can pass an existing EmailSender instance directly to the email argument of EmailHandler or MultiEmailHandler.

    Note: Red Mail creates a copy of the EmailSender instance to ensure that setting attributes like subject, sender, or receivers on the handler does not affect the original instance used elsewhere in your application.

    from redmail import EmailSender, EmailHandler
    
    hdlr = EmailHandler(
        email=EmailSender(host="localhost", port=0),
        subject="A log record",
        receivers=["me@example.com"],
    )
  6. Optimize sending multiple emails by keeping the connection open

    master

    By default, Red Mail opens and closes the SMTP connection for every email sent. For high-volume sending, you should keep the connection open to improve performance. You can do this using a context manager (with email:) or by manually calling .connect() and .close().

    # Option 1: Using a context manager (Recommended)
    with email:
        email.send(subject='msg 1', sender='me@ex.com', receivers=['a@ex.com'])
        email.send(subject='msg 2', sender='me@ex.com', receivers=['b@ex.com'])
    
    # Option 2: Manual connect/close
    try:
        email.connect()
        email.send(subject='msg 1', sender='me@ex.com', receivers=['a@ex.com'])
        email.send(subject='msg 2', sender='me@ex.com', receivers=['b@ex.com'])
    finally:
        email.close()
  7. Add custom email headers

    master

    Pass a dictionary to the headers parameter in .send() to add or override email headers. This can be used to set custom Importance, Date, or even override standard headers like From, To, Cc, Bcc, Date, and Message-ID.

    import datetime
    
    email.send(
        subject='email subject',
        sender="The Sender <me@example.com>",
        receivers=['you@example.com'],
        headers={
            "Importance": "high",
            "Date": datetime.datetime(2021, 1, 31, 6, 56, 46)
        }
    )
  8. Send emails with CC, BCC, and Aliases

    master

    Use the cc and bcc parameters to include carbon copy and blind carbon copy recipients. You can also use aliases by providing a string in the format "Name <email@example.com>" for both sender and receivers. The alias is displayed to the user, but the actual email address is still usable.

    # CC and BCC
    email.send(
        subject='email subject',
        sender="me@example.com",
        receivers=['you@example.com'],
        cc=['also@example.com'],
        bcc=['outsider@example.com']
    )
    
    # Using Aliases
    email.send(
        subject='email subject',
        sender="The Sender <me@example.com>",
        receivers=['The Receiver <you@example.com>']
    )
  9. Send emails with Text, HTML, or both

    master

    You can define the body of your email using the text parameter for plain text, the html parameter for HTML content, or both to provide a multi-part message.

    # Plain text
    email.send(
        subject='email subject',
        sender="me@example.com",
        receivers=['you@example.com'],
        text="Hi, this is an email."
    )
    
    # HTML body
    email.send(
        subject='email subject',
        sender="me@example.com",
        receivers=['you@example.com'],
        html="""
            <h1 style='color: red;'>Hi,</h1>
            <p>this is an email.</p>
        """
    )
    
    # Both text and HTML
    email.send(
        subject='email subject',
        sender="me@example.com",
        receivers=['you@example.com'],
        text="Hi, this is an email.",
        html="""
            <h1>Hi,</h1>
            <p>this is an email.</p>
        """
    )
  10. Configure template paths in Red Mail

    master

    You can tell Red Mail where your HTML and text templates are located by using set_template_paths(). Red Mail will then automatically create the necessary Jinja environments for you. You can also specify custom paths for rendering embedded tables using html_table and text_table.

    from redmail import EmailSender
    
    email = EmailSender(host="localhost", port=0)
    
    # Set standard template paths
    email.set_template_paths(
        html="path/html/templates",
        text="path/text/templates",
    )
    
    # Optionally set custom paths for embedded tables
    email.set_template_paths(
        html_table="path/html/tables",
        text_table="path/text/tables",
    )
  11. Set default email attributes on EmailSender

    master

    You can set default values for attributes like subject, receivers, sender, etc., directly on the EmailSender instance. These defaults will be used by .send() if the specific attribute is not provided in the method call.

    email = EmailSender(host='localhost', port=0)
    email.subject = "email subject"
    email.receivers = ["you@example.com"]
    
    # This uses the default subject and receiver set above
    email.send(
        sender="me@example.com",
        subject="important email"
    )