MailSlurp logo

guides

Sending long emails in Python without breaking delivery

Use Python and smtplib to send long email content safely with MIME structure, size controls, and transport-aware formatting.

Long emails fail for predictable reasons:

  • message size too large after encoding,
  • malformed MIME structure,
  • poor line wrapping for transport,
  • or weak retries around temporary SMTP failures.

This guide focuses on the part teams usually skip: transport-aware structure.

What "long email" means technically

Length issues are not only about character count.

  • HTML templates with inline CSS increase payload quickly.
  • Base64 attachments expand message size significantly.
  • Poorly wrapped plain text can trigger transport inconsistencies.

If your emails include media-heavy content, treat size as an explicit test condition.

Use Python's standard library first:

  • smtplib for SMTP session and delivery.
  • email.mime.multipart.MIMEMultipart for structured messages.
  • email.mime.text.MIMEText for text and HTML parts.
  • email.mime.base.MIMEBase for attachments.

This gives enough control for production-safe long messages.

Structure messages for reliability

  1. Build multipart/alternative for text + HTML bodies.
  2. Add attachments only when required.
  3. Set explicit charset (utf-8) for body parts.
  4. Keep subject, from, and recipient headers normalized.

SMTP session controls to include

  • TLS/STARTTLS enabled by default.
  • Explicit timeout.
  • Authentication error handling (535/530).
  • Retry logic for temporary 4xx responses.
  • Observability around message ID and send latency.

Example code

Imports

import smtplib, ssl
import os
from os.path import basename

# get an api key at https://app.mailslurp.com/sign-up
import mailslurp_client
from mailslurp_client import CreateInboxDto

api_key = os.environ.get('API_KEY')
assert api_key is not None

# create a mailslurp configuration
configuration = mailslurp_client.Configuration()
configuration.api_key['x-api-key'] = api_key
context = ssl.create_default_context()

Send long message example

from email.mime.text import MIMEText

with mailslurp_client.ApiClient(configuration) as api_client:
    inbox_controller = mailslurp_client.InboxControllerApi(api_client)
    inbox1 = inbox_controller.create_inbox_with_options(CreateInboxDto(inbox_type="SMTP_INBOX"))
    inbox2 = inbox_controller.create_inbox_with_options(CreateInboxDto(inbox_type="SMTP_INBOX"))
    smtp_access = inbox_controller.get_imap_smtp_access(inbox_id=inbox1.id)

    # create long message
    text = ""
    for i in range(1, 42):
        text += "This is line {}\n".format(i)

    context = ssl.create_default_context()
    try:
        server = smtplib.SMTP(smtp_access.secure_smtp_server_host, smtp_access.secure_smtp_server_port)
        server.ehlo()
        server.starttls(context=context)
        server.ehlo("test_client")
        server.login(smtp_access.smtp_username, smtp_access.smtp_password)
        # recipients
        subject = "A message with a 41-line body"
        from_address = inbox1.email_address
        to_address = inbox2.email_address
        # send message
        message = MIMEText(text)
        # Set the email subject and 'From' and 'To' headers
        message["Subject"] = subject
        message["From"] = from_address
        message["To"] = to_address
        server.sendmail(from_address, to_address, message.as_string())

        # now fetch email from inbox2
        wait_for_controller = mailslurp_client.WaitForControllerApi(api_client)
        email = wait_for_controller.wait_for_latest_email(inbox_id=inbox2.id)
        assert email.subject == subject

        # assert sent all lines
        assert "This is line 41" in email.body
    finally:
        server.quit()

Pre-send checklist for long messages

Check Why it matters
Rendered size budget Prevent provider rejections and clipping
Text fallback present Improve accessibility and client compatibility
Links/token format validated Catch broken flow behavior before delivery
Attachment MIME type checked Avoid client-side corruption
Delivery timeout defined Prevent hidden queue or throttling failures

When to move beyond raw SMTP scripts

If you need repeatable release checks, add API-based inbox validation:

That combination catches both send-time and receive-time regressions.