Skip to content

Add support for inline embedded images in email_send_message function #17789

@zzstoatzz

Description

@zzstoatzz

related to #17788

Current Behavior

The email_send_message function in prefect-email currently only supports sending images as attachments using the attachments parameter, which adds files with Content-Disposition: attachment.

Proposed Enhancement

Extend the function to support embedding images inline within HTML email content using the Content-ID mechanism and MIME multipart/related structure.

  1. Add a new parameter to email_send_message:
    inline_images: Optional[dict[str, str]] = None

where keys are content IDs and values are file paths

For each inline image:

Read the image file and create a MIMEImage part
Set the Content-ID header with the specified ID
Add the part to the message with proper MIME structure

The implementation would look something like:

from email.mime.image import MIMEImage

# Add after handling attachments
for cid, filepath in (inline_images or {}).items():
    with open(filepath, "rb") as img_file:
        img = MIMEImage(img_file.read())
        img.add_header('Content-ID', f'<{cid}>')
        img.add_header('Content-Disposition', 'inline')
        message.attach(img)

Example Use

email_send_message(
    email_server_credentials=credentials,
    subject="Report with Chart",
    msg="""
    <html>
      <body>
        <p>Here's the monthly chart:</p>
        <img src="cid:chart1">
      </body>
    </html>
    """,
    email_to="recipient@example.com",
    inline_images={"chart1": "/path/to/chart.png"}
)

Additional context

This should be possible using only the stdlib email library we're already using

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementAn improvement of an existing feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions