AlgoInsight

Q&A

How to send emails using Python

By AlgoInsight Team2026-06-07frontendweb-developmenthtmlpython

Overview

Sending email in Python means talking to an SMTP (Simple Mail Transfer Protocol) server - your own, your provider's (Gmail, Outlook), or a transactional service (SendGrid, SES, Mailgun). The standard library gives you smtplib for the connection and email for composing the message. Always use a secure connection (TLS/SSL) and keep credentials out of code.

graph LR
    A[Build message: EmailMessage] --> B[Connect: smtplib.SMTP]
    B --> C[Secure: starttls]
    C --> D[Authenticate: login]
    D --> E[Send: send_message]
    E --> F[Recipient inbox]
    style A fill:#1e1b4b,color:#fff

Basic Plain-Text Email (modern API)

import smtplib
from email.message import EmailMessage
import os

msg = EmailMessage()
msg["Subject"] = "Hello from Python"
msg["From"] = "you@example.com"
msg["To"] = "friend@example.com"
msg.set_content("This is the plain-text body.")

with smtplib.SMTP("smtp.gmail.com", 587) as server:
    server.starttls()                          # upgrade to encrypted connection
    server.login("you@example.com", os.environ["EMAIL_PASSWORD"])
    server.send_message(msg)
print("Sent!")

Key steps: build the EmailMessage, open an SMTP connection (port 587 for STARTTLS), call starttls() to encrypt, login(), then send_message().

SSL Instead of STARTTLS

You can connect over SSL from the start (port 465) with SMTP_SSL:

with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
    server.login("you@example.com", os.environ["EMAIL_PASSWORD"])
    server.send_message(msg)

HTML Email (with a plain-text fallback)

msg = EmailMessage()
msg["Subject"] = "HTML Email"
msg["From"] = "you@example.com"
msg["To"] = "friend@example.com"
msg.set_content("Plain-text fallback for non-HTML clients.")
msg.add_alternative("""
    <html><body>
      <h1 style="color:#6366f1;">Hello!</h1>
      <p>This is an <strong>HTML</strong> email.</p>
    </body></html>
""", subtype="html")

add_alternative attaches an HTML version; clients show HTML if they can, else the plain text.

Adding an Attachment

with open("report.pdf", "rb") as f:
    msg.add_attachment(
        f.read(),
        maintype="application",
        subtype="pdf",
        filename="report.pdf",
    )

Multiple Recipients

msg["To"] = "a@example.com, b@example.com"
msg["Cc"] = "manager@example.com"
# Bcc: pass recipients explicitly to send and DON'T add a Bcc header
server.send_message(msg, to_addrs=["a@example.com", "b@example.com", "secret@example.com"])

Security Essentials

Higher-Level Options

For production volume and deliverability, prefer a transactional email API over raw SMTP:

Why This Matters in Interviews

This tests practical stdlib usage and security awareness. Know the smtplib + email.message.EmailMessage flow (build → connect → starttls → login → send_message), the difference between STARTTLS (587) and SMTP_SSL (465), and how to add HTML and attachments. The strongest signals: never hard-coding credentials, using TLS, app passwords/OAuth for Gmail, and choosing an API service for high-volume deliverability.

Common Pitfalls

References

More answers