The Python Oracle

How to send an email with Gmail as provider using Python?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Hypnotic Orient Looping

--

Chapters
00:00 Question
00:43 Accepted answer (Score 226)
01:38 Answer 2 (Score 320)
02:25 Answer 3 (Score 149)
04:39 Answer 4 (Score 37)
06:55 Thank you

--

Full question
https://stackoverflow.com/questions/1014...

Answer 2 links:
https://support.google.com/accounts/answ...
https://www.google.com/settings/security...
https://accounts.google.com/DisplayUnloc...

Answer 3 links:
[Create Gmail APP Password!]: https://support.google.com/accounts/answ...
[Then add this code]: https://github.com/JayRizzo/Random_Scrip...
[image]: https://i.stack.imgur.com/25f6j.png
[https://support.google.com/accounts/answ...]: https://support.google.com/accounts/answ...
[image]: https://i.stack.imgur.com/1yPnO.png
https://myaccount.google.com/apppassword...
[image]: https://i.stack.imgur.com/2I1SB.png

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #email #smtp #gmail #smtpauth

#avk47



ANSWER 1

Score 327


def send_email(user, pwd, recipient, subject, body):
    import smtplib

    FROM = user
    TO = recipient if isinstance(recipient, list) else [recipient]
    SUBJECT = subject
    TEXT = body

    # Prepare actual message
    message = """From: %s\nTo: %s\nSubject: %s\n\n%s
    """ % (FROM, ", ".join(TO), SUBJECT, TEXT)
    try:
        server = smtplib.SMTP("smtp.gmail.com", 587)
        server.ehlo()
        server.starttls()
        server.login(user, pwd)
        server.sendmail(FROM, TO, message)
        server.close()
        print 'successfully sent the mail'
    except:
        print "failed to send mail"

if you want to use Port 465 you have to create an SMTP_SSL object:

# SMTP_SSL Example
server_ssl = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server_ssl.ehlo() # optional, called by login()
server_ssl.login(gmail_user, gmail_pwd)  
# ssl server doesn't support or need tls, so don't call server_ssl.starttls() 
server_ssl.sendmail(FROM, TO, message)
#server_ssl.quit()
server_ssl.close()
print 'successfully sent the mail'



ACCEPTED ANSWER

Score 230


You need to say EHLO before just running straight into STARTTLS:

server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()

Also you should really create From:, To: and Subject: message headers, separated from the message body by a blank line and use CRLF as EOL markers.

E.g.

msg = "\r\n".join([
  "From: user_me@gmail.com",
  "To: user_you@gmail.com",
  "Subject: Just a message",
  "",
  "Why, oh why"
  ])

Note:

In order for this to work you need to enable "Allow less secure apps" option in your gmail account configuration. Otherwise you will get a "critical security alert" when gmail detects that a non-Google apps is trying to login your account.




ANSWER 3

Score 166


As of 2024, this is what works:

Go to https://myaccount.google.com/security and make sure 2-step verification in enabled on your account. So for this you can setup an app on your phone like Google Authenticator, authy etc..

Once you have setup "2-Step Verification", from security go to "2-Step verification" again and scroll down to "App Passwords":

enter image description here

Now give your app a name and you will be given a password for your device.

Finally save your password somewhere safe and plugin your email and password into the following script:

import smtplib

YOUR_GOOGLE_EMAIL = '<you@gmail.com>'  # The email you setup to send the email using app password
YOUR_GOOGLE_EMAIL_APP_PASSWORD = '<your-app-password>'  # The app password you generated

smtpserver = smtplib.SMTP_SSL('smtp.gmail.com', 465)
smtpserver.ehlo()
smtpserver.login(YOUR_GOOGLE_EMAIL, YOUR_GOOGLE_EMAIL_APP_PASSWORD)

# Test send mail
sent_from = YOUR_GOOGLE_EMAIL
sent_to = sent_from  #  Send it to self (as test)
email_text = 'This is a test'
smtpserver.sendmail(sent_from, sent_to, email_text)

# Close the connection
smtpserver.close()

For more details see Google Auth Passwords.

OLD Answer: (This no longer works) I ran into a similar problem and stumbled on this question. I got an SMTP Authentication Error but my user name / pass was correct. Here is what fixed it. I read this:

https://support.google.com/accounts/answer/6010255

In a nutshell, google is not allowing you to log in via smtplib because it has flagged this sort of login as "less secure", so what you have to do is go to this link while you're logged in to your google account, and allow the access:

https://www.google.com/settings/security/lesssecureapps

Once that is set (see my screenshot below), it should work.

enter image description here

Login now works:

smtpserver = smtplib.SMTP("smtp.gmail.com", 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
smtpserver.login('me@gmail.com', 'me_pass')

Response after change:

(235, '2.7.0 Accepted')

Response prior:

smtplib.SMTPAuthenticationError: (535, '5.7.8 Username and Password not accepted. Learn more at\n5.7.8 http://support.google.com/mail/bin/answer.py?answer=14257 g66sm2224117qgf.37 - gsmtp')

Still not working? If you still get the SMTPAuthenticationError but now the code is 534, its because the location is unknown. Follow this link:

https://accounts.google.com/DisplayUnlockCaptcha

Click continue and this should give you 10 minutes for registering your new app. So proceed to doing another login attempt now and it should work.

UPDATE: This doesn't seem to work right away you may be stuck for a while getting this error in smptlib:

235 == 'Authentication successful'
503 == 'Error: already authenticated'

The message says to use the browser to sign in:

SMTPAuthenticationError: (534, '5.7.9 Please log in with your web browser and then try again. Learn more at\n5.7.9 https://support.google.com/mail/bin/answer.py?answer=78754 qo11sm4014232igb.17 - gsmtp')

After enabling 'lesssecureapps', go for a coffee, come back, and try the 'DisplayUnlockCaptcha' link again. From user experience, it may take up to an hour for the change to kick in. Then try the sign-in process again.

You many now also need create an app password by following the steps under section "Create & use app passwords" here: support.google.com/accounts/answer/185833




ANSWER 4

Score 44


This Works

Create Gmail APP Password!

After you create that then create a file called sendgmail.py

Then add this code:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# =============================================================================
# Created By  : Jeromie Kirchoff
# Created Date: Mon Aug 02 17:46:00 PDT 2018
# =============================================================================
# Imports
# =============================================================================
import smtplib

# =============================================================================
# SET EMAIL LOGIN REQUIREMENTS
# =============================================================================
gmail_user = 'THEFROM@gmail.com'
gmail_app_password = 'YOUR-GOOGLE-APPLICATION-PASSWORD!!!!'

# =============================================================================
# SET THE INFO ABOUT THE SAID EMAIL
# =============================================================================
sent_from = gmail_user
sent_to = ['THE-TO@gmail.com', 'THE-TO@gmail.com']
sent_subject = "Hey Friends!"
sent_body = ("Hey, what's up? friend!\n\n"
             "I hope you have been well!\n"
             "\n"
             "Cheers,\n"
             "Jay\n")

email_text = """\
From: %s
To: %s
Subject: %s

%s
""" % (sent_from, ", ".join(sent_to), sent_subject, sent_body)

# =============================================================================
# SEND EMAIL OR DIE TRYING!!!
# Details: http://www.samlogic.net/articles/smtp-commands-reference.htm
# =============================================================================

try:
    server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    server.ehlo()
    server.login(gmail_user, gmail_app_password)
    server.sendmail(sent_from, sent_to, email_text)
    server.close()

    print('Email sent!')
except Exception as exception:
    print("Error: %s!\n\n" % exception)

So, if you are successful, will see an image like this:

I tested by sending an email from and to myself.

Successful email sent.

Note: I have 2-Step Verification enabled on my account. App Password works with this! (for gmail smtp setup, you must go to https://support.google.com/accounts/answer/185833?hl=en and follow the below steps)

This setting is not available for accounts with 2-Step Verification enabled. Such accounts require an application-specific password for less secure apps access.

Less secure app access... This setting is not available for accounts with 2-Step Verification enabled.

Clarification

Navigate to https://myaccount.google.com/apppasswords and create an APP Password as stated above.

https://myaccount.google.com/apppasswords