Send Email via Gmail and SMTP

In our previous post Send HTML Email With Attachments via SMTP we explained how to build a message and send it through an SMTP server in Python. Google's email provider, Gmail, fully supports the SMTP protocol at the smtp.gmail.com address. However, trying to run the following test code to send an email via Gmail from Python will result in an authentication error:

from email.message import EmailMessage
import smtplib
sender = "sender@gmail.com"
recipient = "recipient@example.com"
message = "Hello world!"
email = EmailMessage()
email["From"] = sender
email["To"] = recipient
email["Subject"] = "Sent from Python!"
email.set_content(message)
smtp = smtplib.SMTP_SSL("smtp.gmail.com")
smtp.login(sender, "gmail_password_123")
smtp.sendmail(sender, recipient, email.as_string())
smtp.quit()

This code generates more or less the following exception:

Traceback (most recent call last):
File "test_gmail.py", line 15, in
    smtp.login(sender, "gmail_password_123")
...
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials x12-20020ab0640c000000b00384293c4199sm1462401uao.23 - gsmtp')

Even though the Gmail email address and password are correct, the error occurs because, as of May 30, 2022, Google no longer supports sending emails via the SMTP protocol using our account's password. However, we can still make use of this code and the SMTP protocol if we generate a special key (an App password, in Google's terminology) for our Python program, instead of using Google's password, which entails a significant risk for the security of our account.

To generate an App password, the Gmail account from which we want to send the email must have 2-step verification activated. Without this requirement it is not possible to create a special key for our Python code. So the first step is to go to our Google account settings, and within the "Security" section activate the 2-step verification. Once this is done, the "App passwords" option will become available in the same section:

/images/send-email-via-gmail-and-smtp/gmail-app-passwords.png

After clicking on that option we will be required to select the application which we want to generate the special password for. Select the last option "Other (Custom name)", as shown in the image:

/images/send-email-via-gmail-and-smtp/gmail-generate-app-password.png

Google will ask us to write a name for our application. Type in "Python" or whatever you want:

/images/send-email-via-gmail-and-smtp/gmail-write-app-password.png

Press the "Generate" button and a 16-digit password will be displayed on screen (for example, fzolfunvtkqzovgv). Make sure to copy the key because it will not be shown again.

Now it only remains to paste the generated password into our Python code, passing it as an argument to smtp.login():

from email.message import EmailMessage
import smtplib
sender = "sender@gmail.com"
recipient = "recipient@example.com"
message = "Hello world!"
email = EmailMessage()
email["From"] = sender
email["To"] = recipient
email["Subject"] = "Sent from Python!"
email.set_content(message)
smtp = smtplib.SMTP_SSL("smtp.gmail.com")
smtp.login(sender, "fzolfunvtkqzovgv")
smtp.sendmail(sender, recipient, email.as_string())
smtp.quit()

Done! You are now able to send emails from your Gmail account and Python via SMTP. In order to send emails in HTML format and/or with file attachments, check out the aforementioned post: Send HTML Email With Attachments via SMTP.