The honest how-to
For a personal notification script, Gmail over SMTP works: enable 2FA, generate an app password, connect to smtp.gmail.com:587 with STARTTLS, send. Every tutorial shows it because it does work.
import smtplib from email.message import EmailMessage msg = EmailMessage() msg["From"], msg["To"], msg["Subject"] = "[email protected]", "[email protected]", "Backup done" msg.set_content("Finished at 02:00.") with smtplib.SMTP("smtp.gmail.com", 587) as s: s.starttls(); s.login("[email protected]", "app-password"); s.send_message(msg)
Why it breaks as a product
The trap is scale one: the day your script serves users instead of you. App passwords expire and trip security alerts. The daily sending cap is built for a person. Your mail authenticates as gmail.com, not your domain, so you can't build sender reputation. And when Google changes auth policy, your product breaks on their schedule.
Gmail is a mailbox. Production email needs a sending platform behind it: your domain, your reputation, delivery events, and no password that expires mid-quarter.
Put numbers on the cap: a personal Gmail account can send 500 emails a day, a Workspace account 2,000, and if the mail is cold outreach the practical ceiling is 30 to 50 a day per mailbox before flags start. The enforcement side has teeth now too: cross a 0.30 percent spam rate and Gmail, Yahoo, and Microsoft will block you outright.
For Gmail specifically, domain reputation matters far more than IP reputation. IP memory runs about 120 days, and a dedicated IP is only worth having past a million emails a month; below that, send from an authenticated subdomain and let the domain carry the trust. Gmail is most of the game anyway. In our own user base, 78 percent of people live in a Google mailbox.
Full parameters and responses live in the REST API docs and the API reference.
Go deeper
Here is the thing an app password never fixes. The real answer to "how do I send email in Python" is not a cleaner Gmail workaround, it is skipping the workaround. Describe the send to Claude, Cursor, or Codex and our MCP server sends it on the same account, on your own domain, with no app password to generate or rotate.
The platform version of this page is send email with Python: same five lines, your own domain, message IDs back. Outlook shop? Same story, different trap. Gmail is the strictest audience you have, which makes SPF, DKIM and DMARC authentication non negotiable and inbox placement the number to watch.
FAQ
How do I send email via Gmail in Python?
Enable 2FA, create an app password, and use smtplib with smtp.gmail.com port 587 and STARTTLS. Reasonable for personal scripts; wrong for products, because of expiring passwords, daily caps, and no domain reputation.
Why does Gmail block my Python script?
Plain passwords are retired, so scripts need app passwords over 2FA, and unusual sending patterns still trigger security blocks. Products should send through an email API with their own authenticated domain instead.