Skip to content
Advertisement

How do I now (since June 2022) send an email via Gmail using a Python script?

I had a Python script which did this. I had to enable something in the Gmail account. For maybe 3 years the script then ran like this:

import smtplib, ssl
...
subject = 'some subject message'
body = """text body of the email"""
sender_email = 'my_gmail_account_name@gmail.com'
receiver_email = 'some_recipient@something.com'

# Create a multipart message and set headers
message = MIMEMultipart()
message['From'] = 'Mike'
message['To'] = receiver_email
message['Subject'] = subject
# Add body to email
message.attach(MIMEText(body, 'plain'))
# Open file in binary mode
with open( client_zip_filename, 'rb') as attachment:
    # Add file as application/octet-stream
    # Email client can usually download this automatically as attachment
    part = MIMEBase('application', 'octet-stream')
    part.set_payload(attachment.read())
# Encode file in ASCII characters to send by email    
encoders.encode_base64(part)
# Add header as key/value pair to attachment part
part.add_header(
    'Content-Disposition',
    f'attachment; filename={subject}',
)
# Add attachment to message and convert message to string
message.attach(part)
text = message.as_string()
# Log in to server using secure context and send email
context = ssl.create_default_context()
with smtplib.SMTP_SSL('smtp.gmail.com', 465, context=context) as server:
    print( 'waiting to login...')
    server.login(sender_email, password)
    print( 'waiting to send...')
    server.sendmail(sender_email, receiver_email, text)
print( 'email appears to have been sent')

In May or so of this year I got a message from Google saying that authority to use emails from scripts would be tightened. “Oh dear”, I thought.

Some time in June I found that the above script no longer works, and raises an exception, specifically on the line server.login(sender_email, password):

  ...
  File "D:My documentssoftware projectsoperativesysadmin_pysrcjob_backup_routine__main__.py", line 307, in main
    server.login(sender_email, password)
  File "c:usersmikeappdatalocalprogramspythonpython39libsmtplib.py", line 745, in login
    raise last_exception
  File "c:usersmikeappdatalocalprogramspythonpython39libsmtplib.py", line 734, in login
    (code, resp) = self.auth(
  File "c:usersmikeappdatalocalprogramspythonpython39libsmtplib.py", line 657, in auth
    raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. 
Learn more atn5.7.8  https://support.google.com/mail/?p=BadCredentials p14-20020aa7cc8e000000b00435651c4a01sm8910838edt.56 - gsmtp')

… I was thus not entirely surprised by this, and have now gone looking for a solution.

  • I have got this idea that the way forward is something called “OAuth consent” (I don’t have any idea what this is…)

  • I found this answer and tried to follow the steps there. Here is my account of trying to follow step 1:

  • I went to this Google configuration page and chose “my_gmail_account_name”, the account I want to send emails from …

  • new “project”, name: test-project-2022-07-18

  • location: default (“No organisation”)

  • clicked Create

  • clicked NEXT

  • clicked ENABLE

  • clicked the icon to enable the “Google Developer Console”

  • in the hamburger menu (top left) there is an item “APIs and services” … one item there is “Credentials” – clicked

  • one item in the left-hand list is “OAuth consent screen”

  • another item is “Credentials”. Clicked this: then, at the top, “+ CREATE CREDENTIALS”

  • in the dropdown menu, choose “OAuth Client ID”

  • clicked “CONFIGURE CONSENT SCREEN”

  • radio buttons: “Internal” and “External”. chose latter.

  • clicked “CREATE”

  • under “App information”:

  • “App name”: sysadmin_py

  • “User support email”: my_gmail_account_name@gmail.com

  • “Developer contact information”: my_gmail_account_name@gmail.com

  • clicked “SAVE AND CONTINUE”

  • then find myself on a page about “SCOPES”, with a button “ADD OR REMOVE SCOPES”…

At this point I’m meant to be following “Step 1” instruction “d. Select the application type Other, enter the name “Gmail API Quickstart” and click the Create button”… but nothing of this kind is in view!

The update to that answer was done in 2021-04. A year later the interface in Google appears to have changed radically. Or maybe I have taken the wrong path and disappeared down a rabbit hole.

I have no idea what to do. Can anyone help?

Advertisement

Answer

Google has recently made changes to access of less secure apps (read here: https://myaccount.google.com/lesssecureapps).

In order to make your script work again, you’ll need to make a new app password for it. Directions to do so are below:

  • Go to My Account in Gmail and click on Security. After that, scroll down to choose the Signing into Google option.
  • Now, click on App Password. (Note: You can see this option when two-step authentication is enabled). To enable two-step authentication:
    1. From the Signing into Google, click on the Two-step Verification option and then enter the password.
    2. Then Turn ON the two-step verification by entering the OTP code received on the mobile.

(Here’s a quick link to the same page: https://myaccount.google.com/apppasswords)

  • Here, you can see a list of applications, choose the required one.
  • Next, pick the Select Device option and click on the device which is being used to operate Gmail.
  • Now, click on Generate.
  • After that, enter the Password shown in the Yellow bar.
  • Lastly, click on Done.

(Source: https://www.emailsupport.us/blog/gmail-smtp-not-working/)

Simply switch out the password the script is using for this newly generated app password. This worked for me and I wish the same for you.

I hope this helps!

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement