22

I've been trying (and failing) to figure out how to send email via Python.

Trying the example from here: http://docs.python.org/library/smtplib.html#smtplib.SMTP

but added the line server = smtplib.SMTP_SSL('smtp.gmail.com', 465) after I got a bounceback about not having an SSL connection.

Now I'm getting this:

Traceback (most recent call last):
  File "C:/Python26/08_emailconnects/12_29_EmailSendExample_NotWorkingYet.py", line 37, in <module>
    server = smtplib.SMTP('smtp.gmail.com', 65)
  File "C:\Python26\lib\smtplib.py", line 239, in __init__
    (code, msg) = self.connect(host, port)
  File "C:\Python26\lib\smtplib.py", line 295, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "C:\Python26\lib\smtplib.py", line 273, in _get_socket
    return socket.create_connection((port, host), timeout)
  File "C:\Python26\lib\socket.py", line 512, in create_connection
    raise error, msg
error: [Errno 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
>>> 

Thoughts?


server = smtplib.SMTP("smtp.google.com", 495) gives me a timeout error. just smtplib.smtp("smtp.google.com", 495) gives me "SSLError: [Errno 1] _ssl.c:480: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol" (see below).

I'm trying different ports and now I'm getting a completely new error. I'll just post the whole bit of code, I'm probably making some rookie mistake.

"

import smtplib

mailuser = 'MYEMAIL@gmail.com'

mailpasswd = 'MYPASSWORD'

fromaddr = 'MYEMAIL@gmail.com'

toaddrs = 'MYEMAIL2@gmail.com'

msg = 'Hooooorah!'

print msg

server = smtplib.SMTP_SSL('smtp.google.com')

server = smtplib.SMTP_SSL_PORT=587

server.user(mailuser)

server.pass_(mailpasswd)

server.set_debuglevel(1)

server.sendmail(fromaddr, toaddrs, msg)

server.quit()

"

and then I get this error message: "

Traceback (most recent call last):
  File "C:/Python26/08_emailconnects/12_29_eMAILSendtryin_stripped.py", line 16, in <module>
    server = smtplib.SMTP_SSL('smtp.google.com')
  File "C:\Python26\lib\smtplib.py", line 749, in __init__
    SMTP.__init__(self, host, port, local_hostname, timeout)
  File "C:\Python26\lib\smtplib.py", line 239, in __init__
    (code, msg) = self.connect(host, port)
  File "C:\Python26\lib\smtplib.py", line 295, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "C:\Python26\lib\smtplib.py", line 755, in _get_socket
    self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile)
  File "C:\Python26\lib\ssl.py", line 350, in wrap_socket
    suppress_ragged_eofs=suppress_ragged_eofs)
  File "C:\Python26\lib\ssl.py", line 118, in __init__
    self.do_handshake()
  File "C:\Python26\lib\ssl.py", line 293, in do_handshake
    self._sslobj.do_handshake()
SSLError: [Errno 1] _ssl.c:480: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

"

note that actually the which looks like "server = smtplib.SMTPSSLPORT=587" is actually "server = smtplib.SMTP underscore SSL underscore PORT=587", there's some sort of formatting thing going on here.

Tim Post
  • 33,371
  • 15
  • 110
  • 174
Chatter
  • 241
  • 1
  • 3
  • 4
  • Note: please don't assume that answers here are sorted by time like a thread of emails. Answers may be raised or lowered by means of voting and editing. Thus, if you want to reply to someone, don't post an answer - leave a comment or update the question instead. – Federico A. Ramponi Dec 30 '08 at 03:09

11 Answers11

29

The following code works for me:

import smtplib

FROMADDR = "my.real.address@gmail.com"
LOGIN    = FROMADDR
PASSWORD = "my.real.password"
TOADDRS  = ["my.real.address@gmail.com"]
SUBJECT  = "Test"

msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n"
       % (FROMADDR, ", ".join(TOADDRS), SUBJECT) )
msg += "some text\r\n"

server = smtplib.SMTP('smtp.gmail.com', 587)
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.login(LOGIN, PASSWORD)
server.sendmail(FROMADDR, TOADDRS, msg)
server.quit()

I'm using Python 2.5.2.

Edit: changed port from 25 to 587 as suggested by ΤΖΩΤΖΙΟΥ, and dropped the second ehlo(). Now I would love to know why port 25 works perfectly from my machine (and port 465 does not).

Federico A. Ramponi
  • 46,145
  • 29
  • 109
  • 133
  • 1
    Using Python 2.4.4 and your example I received the following error: SMTP AUTH extension not supported by server. I was able to get around it by adding a second ehlo() after the call to starttls() – Jataro Jul 21 '09 at 05:45
  • 1
    The call to server.ehlo() is unneeded. server.sendmail(...) handles it as necessary. – Jeff Jan 17 '10 at 07:28
  • When sending through gmail my code requires server.ehlo() before the starttls(), with python 2.5.2 – David Sykes Sep 15 '11 at 14:26
  • 2
    I am using the above code,but i got the error => **ssl.SSLError: [Errno 1] _ssl.c:503: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol**. – Tushar Patil Mar 24 '14 at 11:42
8

The correct way to connect to GMail using SSL is:

server = smtplib.SMTP('smtp.gmail.com', 587)

Port 465 seems to cause delays. Both ports are specified in a GMail FAQ.

Note that use of port 587 is more common for SMTP over SSL, although this is just trivial information, it has no other practical use.

This answer is provided as community wiki in order to be chosen as "the" answer. Please improve as needed.

tzot
  • 92,761
  • 29
  • 141
  • 204
6

Here's a simple throw away solution. Meant to paste this earlier, but fell asleep at my chair.


import smtplib
import email
import os

username = "user@gmail.com"
passwd = "password"

def mail(to, subject, text, attach):
   msg = MIMEMultipart()

   msg['From'] = username
   msg['To'] = to
   msg['Subject'] = subject

   msg.attach(MIMEText(text)) 

   part = MIMEBase('application', 'octet-stream')
   part.set_payload(open(attach, 'rb').read())
   Encoders.encode_base64(part)
   part.add_header('Content-Disposition',
           'attachment; filename="%s"' % os.path.basename(attach))
   msg.attach(part)

   server = smtplib.SMTP("smtp.gmail.com", 495)
   server.ehlo()
   server.starttls()
   server.ehlo()
   server.login(username, passwd)
   server.sendmail(username, to, msg.as_string())
   server.close()

mail("you", "hi", "hi", "webcam.jpg")

It's my assumption that most people on this thread that have had successful attempts with their code aren't on win32. ;)

*edit: See http://docs.python.org/library/email-examples.html for some good "official" examples.

ジョージ
  • 1,476
  • 1
  • 22
  • 29
EndUsr
  • 71
  • 2
  • 4
    My code definitely needs 2 ehlo commands. Code does not work without ehlo. – Jiri Oct 15 '10 at 06:56
  • @Jiri You're right. I verify here with Python 2.5 (stuck here because it's all Saurik has available on Cydia), it just needs an extra `ehlo()` after `starttls()`. `server.set_debuglevel(1)` was helpful in this regard. Of course, no second `ehlo` is needed post python 2.5. But it seems to also be okay. Now I have python email code that works from 2.5 thru 2.7. Including running on iOS. – Steven Lu Dec 31 '14 at 09:40
6

The problem is due to a bug in Python. Trying to create a connection with SMTP_SSL will fail with "SMTPServerDisconnected: please run connect() first."

A fix has been committed, so you can patch your local copy. See the attachment named "smtplib_72551.diff".

(Note: SMTP_SSL is a new class added to Python 2.6/3.0 and later.)

keithb
  • 1,940
  • 16
  • 15
2

Okay, found out that this line of code does the trick!

server = smtplib.SMTP('smtp.gmail.com', 587 )

Turned out to be GMAIL didn't support SSL on port 25 (and port 465 caused a hang for some reason).

Thanks guys!

Chatter
  • 241
  • 1
  • 3
  • 4
  • Well, written it on Dec 29: http://stackoverflow.com/questions/399129/failing-to-send-email-with-the-python-example#399140 – Abgan Jan 02 '09 at 15:22
1
from smtplib import SMTP_SSL as SMTP
from email.mime.text import MIMEText

HOST = 'smtp.gmail.com'
PORT = 465

USERNAME = 'oltjano13@gmail.com'
PASSWORD = ''

SENDER = 'oltjano13@gmail.com'
RECIPIENT = 'oltjano13@gmail.com'

text_subtype = 'plain'

with open('textfile', 'rb') as f:
    msg = MIMEText(f.read(), text_subtype)


msg['Subject'] = 'Python Script'
msg['From'] = SENDER
msg['To'] = RECIPIENT

try:
    connection = SMTP(HOST, PORT)
    connection.login(USERNAME, PASSWORD)
    connection.sendmail(SENDER, RECIPIENT, msg.as_string())
except Exception, e:
    print(e)

The above code works fine for me. As you can see the PORT = 465 is being used in this example since I am using SSL. If you plan to use the port 587 then TLS is required.

orthodoxpirate
  • 1,934
  • 2
  • 17
  • 17
1

Incorrect port maybe? I'm using 587 for smtp.gmail.com and it works.

Abgan
  • 3,696
  • 22
  • 31
1

You should check your port, I'm not sure that google's SMTP port is 65, that would explain the timeout.

Modify your sources as such:

smtplib.SMTP_SSL('smtp.google.com', 465)

If, however, you are certain that it ought to work and it doesn't, it appears that there are some problems with smtplib.SMTP_SSL, and there's an available patch for it here.

EndUsr
  • 71
  • 2
0
import smtplib

content = 'example email stuff here'

mail = smtplib.SMTP('smtp.gmail.com', 587)

mail.ehlo()

mail.starttls()

mail.login('email@gmail.com','password')

mail.sendmail('email@gmail.com', 'email@yahoo.com', content)

mail.close()
beroe
  • 11,784
  • 5
  • 34
  • 79
Super Saiyan
  • 43
  • 1
  • 2
  • 7
0

Then I had trie to sent email through smtp.gmail.com, I had the same errors. In my case the Internet provider had close the port 25 (and also 587 and other) for outgoing connections from the IP addresses (from my network) to the external network, leaving open the 25th port only for its mail server. So, at first try:

telnet smtp.gmail.com 587

(587 it your port)

By doing this you can understand, if your port is closed by the Internet provider. You can contact your provider and ask them to open a port for you. My solution was connecting to other network (with open port) Here is the code I used:

gmailaddress = "youremailadress@gmail.com"
gmailpassword = "7777777"
mailto = "youremailadress@gmail.com"
msg = input("What is your message? \n ")
mailServer = smtplib.SMTP('smtp.gmail.com' , 587)
mailServer.starttls()
mailServer.login(gmailaddress , gmailpassword)
mailServer.sendmail(gmailaddress, mailto , msg)
print(" \n Sent!")
mailServer.quit()```
Andrii
  • 15
  • 6
  • by the way I had allowed permission: https://accounts.google.com/b/0/DisplayUnlockCaptcha and https://myaccount.google.com/lesssecureapps?pli=1&rapt=AEjHL4PExP4TUtfeqZZRtPwo-bR4qZIRJR1g5e4rYH-SlcVZHhXjBYBPp5a18-fk-SDpRLxP2gNDcUoFAvjcwOvBxkcS52Xgug – Andrii Oct 19 '20 at 09:10
0

After a lot of fiddling with the examples e.g here this now works for me:

import smtplib
from email.mime.text import MIMEText

# SMTP sendmail server mail relay
host = 'mail.server.com'
port = 587 # starttls not SSL 465 e.g gmail,port 25 blocked by most ISPs & AWS
sender_email = 'name@server.com'
recipient_email = 'name@domain.com'
password = 'YourSMTPServerAuthenticationPass'
subject = "Server - "
body = "Message from server"

def sendemail(host, port, sender_email, recipient_email, password, subject, body):
    try:
        p1 = f'<p><HR><BR>{recipient_email}<BR>'
        p2 = f'<h2><font color="green">{subject}</font></h2>'
        p3 = f'<p>{body}'
        p4 = f'<p>Kind Regards,<BR><BR>{sender_email}<BR><HR>'
        
        message = MIMEText((p1+p2+p3+p4), 'html')  
        # servers may not accept non RFC 5321 / RFC 5322 / compliant TXT & HTML typos

        message['From'] = f'Sender Name <{sender_email}>'
        message['To'] = f'Receiver Name <{recipient_email}>'
        message['Cc'] = f'Receiver2 Name <>'
        message['Subject'] = f'{subject}'
        msg = message.as_string()

        server = smtplib.SMTP(host, port)
        print("Connection Status: Connected")
        server.set_debuglevel(1)
        server.ehlo()
        server.starttls()
        server.ehlo()
        server.login(sender_email, password)
        print("Connection Status: Logged in")
        server.sendmail(sender_email, recipient_email, msg)
        print("Status: Email as HTML successfully sent")

    except Exception as e:
            print(e)
            print("Error: unable to send email")

# Run
sendemail(host, port, sender_email, recipient_email, password, subject, body)
print("Status: Exit")
social
  • 329
  • 3
  • 8