Failing to send email with the Python example - python

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.

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).

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.

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.)

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.

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!

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.

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

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.

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()

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()```

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")

Related

"gaierror: [Errno -5] No address associated with hostname" while sending email from Azure databricks python notebook

I am trying to send a mail from my Azure databricks notebook via my company SMTP server.
I am able to run the same script on my local machine. And the mail is being sent when running the script from local.
But, when I am running the script from databricks, I am getting the error No address associated with hostname
The script -
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
server = smtplib.SMTP("COMPANY SMTP SERVER", COMPANY_SMTP_PORT)
fromaddr = "username#companyname.com"
toaddr = "username#companyname.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "Email test"
body = "test mail"
msg.attach(MIMEText(body, 'plain'))
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
Error traceback -
gaierror Traceback (most recent call last)
<command-2889814627634467> in <module>
3 from email.mime.text import MIMEText
4
----> 5 server = smtplib.SMTP("COMPANY SMTP SERVER", COMPANY_SMTP_PORT)
6 fromaddr = "username#companyname.com"
7 toaddr = "username#companyname.com"
/usr/lib/python3.8/smtplib.py in __init__(self, host, port, local_hostname, timeout, source_address)
253
254 if host:
--> 255 (code, msg) = self.connect(host, port)
256 if code != 220:
257 self.close()
/usr/lib/python3.8/smtplib.py in connect(self, host, port, source_address)
337 port = self.default_port
338 sys.audit("smtplib.connect", self, host, port)
--> 339 self.sock = self._get_socket(host, port, self.timeout)
340 self.file = None
Can anyone provide some insights as to what might be the issue, and how could I rectify it?
Replace COMPANY SMTP SERVER string with actual host name of the email server.
Was able to resolve by using gmail smtp server to send mails.
Databricks is an external environment to my company's outlook mail server, so white-listing was required for sending mails through company smtp server.

GCP (Google Cloud) VM - Can't send email via Python script with SMTP

So I set up a GCP VM with Ubuntu, from where I want to send regular reports through my mail provider with a python script. The smtp port is 587, and to my understanding the port was formerly closed in GCP environments but should now be available.
My script looks like this:
import smtplib,ssl
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import formatdate
from email import encoders
import time
timestr = time.strftime('(%Y-%m-%d)')
username='me#mydomain.de'
password='secretpw'
send_from = 'me#mydomain.de'
send_to = 'recipient#herdomain.com'
body = 'hello'
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = send_to
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = 'important email'
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.ionos.de')
port = '587'
smtp = smtplib.SMTP('smtp.ionos.de')
smtp.ehlo()
smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to.split(','), msg.as_string())
smtp.quit()
On execution, the machine takes some time before outputting a timeout:
Traceback (most recent call last):
File "test.py", line 25, in <module>
server = smtplib.SMTP('smtp.ionos.de')
File "/usr/lib/python3.8/smtplib.py", line 255, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python3.8/smtplib.py", line 339, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python3.8/smtplib.py", line 310, in _get_socket
return socket.create_connection((host, port), timeout,
File "/usr/lib/python3.8/socket.py", line 808, in create_connection
raise err
File "/usr/lib/python3.8/socket.py", line 796, in create_connection
sock.connect(sa)
TimeoutError: [Errno 110] Connection timed out
I can, however, ping smtp.ionos.de as well as telnet smtp.ionos.de 587 form the cl with result of a working ping and connection.
I also tried this with other email providers including gmail and get stuck with the exact same outcome.
Anyone? Help appreciated, thanks.
Your code has multiple problems:
Connecting to the server twice.
Not specifying the port number when connecting
Not creating an SSL context for encryption.
In your code, replace these lines:
server = smtplib.SMTP('smtp.ionos.de')
port = '587'
smtp = smtplib.SMTP('smtp.ionos.de')
smtp.ehlo()
smtp.starttls()
With:
context = ssl.create_default_context()
smtp = smtplib.SMTP('smtp.ionos.de', 587)
smtp.ehlo()
smtp.starttls(context=context)
Here is a full example tested with a GCP Cloud Function. No libs are needed in requirements.txt. This uses Python 3.9. The code uses an App Password because normal users require 2FA.
import smtplib
import ssl
def send_email(request):
"""Responds to any HTTP request.
Args:
request (flask.Request): HTTP request object.
Returns:
The response text or any set of values that can be turned into a
Response object using
`make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
"""
gmail_user = 'user#gmail.com'
gmail_password = 'YOURPASSWORD'
sent_from = gmail_user
to = ['foo#bar.com']
subject = 'Test e-mail from Python'
body = 'Test e-mail body'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
context = ssl.create_default_context()
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls(context=context)
server.login(gmail_user, gmail_password)
server.sendmail(sent_from, to, body)
server.close()
print('Email sent (print)!')
return f'Email sent (return)!'

How to send an mail from my domain using SMTP in Python?

I am trying to send mail from my domain using below script.
While hitting this line smtplib.SMTP_SSL('mail.abc.com:587') interpreter is hanged until terminate manually.
Can anyone suggest how to resolve this..?
import smtplib
fromaddr = "user#abc.com"
toaddrs = "user1#abc.com"
msg = ("From: %s\r\nTo: %s\r\n\r\n"
% (fromaddr, toaddrs))
msg += str(stdout)
try :
server = smtplib.SMTP_SSL('mail.abc.com:587')
server.set_debuglevel(1)
server.starttls()
server.ehlo
server.login('user#abc.com','******')
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
except smtplib.SMTPException, e :
print e
You don't need SMTP_SSL — use SMTP. It's either SMTP_SSL or SMTP + starttls() but not both.
Default port for SMTP_SSL is 465.

Issue with sending mails from a distribution mail id [Python]

I have seen the following question but I still have a few doubts.
Sending an email from a distribution list
Firstly I have an individual mail account as well as a distribution id used for a group in a particular mail server. I am able to send mails from the distribution mail id through outlook just by specifying the From field. It requires no authentication.
I have been using the following code to send mails through my personal account:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import os
FROMADDR = "myaddr#server.com"
GROUP_ADDR = ['group#server.com']
PASSWORD = 'foo'
TOADDR = ['toaddr#server.com']
CCADDR = ['group#server.com']
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = 'Test'
msg['From'] = FROMADDR
msg['To'] = ', '.join(TOADDR)
msg['Cc'] = ', '.join(CCADDR)
# Create the body of the message (an HTML version).
text = """Hi this is the body
"""
# Record the MIME types of both parts - text/plain and text/html.
body = MIMEText(text, 'plain')
# Attach parts into message container.
msg.attach(body)
# Send the message via local SMTP server.
s = smtplib.SMTP('server.com', 587)
s.set_debuglevel(1)
s.ehlo()
s.starttls()
s.login(FROMADDR, PASSWORD)
s.sendmail(FROMADDR, TOADDR, msg.as_string())
s.quit()
This works perfectly fine. Since I am able to send mail from a distribution mail id through outlook (without any password), is there any way that I can modify this code to send mail through the distribution id? I tried commenting out the
s.ehlo()
s.starttls()
s.login(FROMADDR, PASSWORD)
part but the code gives me the following error:
send: 'mail FROM:<group#server.com> size=393\r\n'
reply: b'530 5.7.1 Client was not authenticated\r\n'
reply: retcode (530); Msg: b'5.7.1 Client was not authenticated'
send: 'rset\r\n'
Traceback (most recent call last):
File "C:\Send_Mail_new.py", line 39, in <module>
s.sendmail(FROMADDR, TOADDR, msg.as_string())
File "C:\Python32\lib\smtplib.py", line 743, in sendmail
self.rset()
File "C:\Python32\lib\smtplib.py", line 471, in rset
return self.docmd("rset")
File "C:\Python32\lib\smtplib.py", line 395, in docmd
return self.getreply()
File "C:\Python32\lib\smtplib.py", line 371, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed
Would someone kindly help me out here?
reply: retcode (530); Msg: b'5.7.1 Client was not authenticated'
This means you need authentication. Outlook is likely using the same authentication for your existing account (since you only changed the From header).

How can I send email using Python?

I am writing a program that sends an email using Python. What I have learned from various forums is the following piece of code:
#!/usr/bin/env python
import smtplib
sender = "sachinites#gmail.com"
receivers = ["abhisheks#cse.iitb.ac.in"]
yourname = "Abhishek Sagar"
recvname = "receptionist"
sub = "Testing email"
body = "who cares"
message = "From: " + yourname + "\n"
message = message + "To: " + recvname + "\n"
message = message + "Subject: " + sub + "\n"
message = message + body
try:
print "Sending email to " + recvname + "...",
server = smtplib.SMTP('smtp.gmail.com:587')
username = 'XYZ#gmail.com'
password = '*****'
server.ehlo()
server.starttls()
server.login(username,password)
server.sendmail(sender, receivers, message)
server.quit()
print "successfully sent!"
except Exception:
print "Error: unable to send email"
But it is simply printing ""Error: unable to send email" and exits out on the terminal. How might I resolve this?
I modified the last two lines to
except Exception, error:
print "Unable to send e-mail: '%s'." % str(error)
I get the following error message :
Traceback (most recent call last):
File "./2.py", line 45, in <module>
smtpObj = smtplib.SMTP('localhost')
File "/usr/lib/python2.6/smtplib.py", line 239, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python2.6/smtplib.py", line 295, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python2.6/smtplib.py", line 273, in _get_socket
return socket.create_connection((port, host), timeout)
File "/usr/lib/python2.6/socket.py", line 514, in create_connection
raise error, msg
socket.error: [Errno 111] Connection refused
If message headers, payload contain non-ascii characters then they should be encoded:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from email.header import Header
from email.mime.text import MIMEText
from getpass import getpass
from smtplib import SMTP_SSL
login, password = 'user#gmail.com', getpass('Gmail password:')
recipients = [login]
# create message
msg = MIMEText('message body…', 'plain', 'utf-8')
msg['Subject'] = Header('subject…', 'utf-8')
msg['From'] = login
msg['To'] = ", ".join(recipients)
# send it via gmail
s = SMTP_SSL('smtp.gmail.com', 465, timeout=10)
s.set_debuglevel(1)
try:
s.login(login, password)
s.sendmail(msg['From'], recipients, msg.as_string())
finally:
s.quit()
If you print the error message, you will likely get a comprehensive description of what error occurred. Try (no pun intended) this:
try:
# ...
except Exception, error:
print "Unable to send e-mail: '%s'." % str(error)
If, after reading the error message, you still do not understand your error, please update your question with the error message and we can help you some more.
Update after additional information:
the error message
socket.error: [Errno 111] Connection refused
means the remote end (e.g. the GMail SMTP server) is refusing the network connection. If you take a look at the smtplib.SMTP constructor, it seems you should change
server = smtplib.SMTP('smtp.gmail.com:587')
to the following.
server = smtplib.SMTP(host='smtp.gmail.com', port=587)
According to the error message, you use the localhost as the SMTP server, then the connection was refused. Your localhost didn't have an SMTP sever running I guess, you need to make sure the SMTP server you connect is valid.

Categories