This code works and sends me an email just fine:
import smtplib
#SERVER = "localhost"
FROM = 'monty@python.com'
TO = ["jon@mycompany.com"] # must be a list
SUBJECT = "Hello!"
TEXT = "This message was sent with Python's smtplib."
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP('myserver')
server.sendmail(FROM, TO, message)
server.quit()
However if I try to wrap it in a function like this:
def sendMail(FROM,TO,SUBJECT,TEXT,SERVER):
import smtplib
"""this is some test documentation in the function"""
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()
and call it I get the following errors:
Traceback (most recent call last):
File "C:/Python31/mailtest1.py", line 8, in <module>
sendmail.sendMail(sender,recipients,subject,body,server)
File "C:/Python31\sendmail.py", line 13, in sendMail
server.sendmail(FROM, TO, message)
File "C:\Python31\lib\smtplib.py", line 720, in sendmail
self.rset()
File "C:\Python31\lib\smtplib.py", line 444, in rset
return self.docmd("rset")
File "C:\Python31\lib\smtplib.py", line 368, in docmd
return self.getreply()
File "C:\Python31\lib\smtplib.py", line 345, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed
Can anyone help me understand why?
While indenting your code in the function (which is ok), you did also indent the lines of the raw message string. But leading white space implies folding (concatenation) of the header lines, as described in sections 2.2.3 and 3.2.3 of RFC 2822 - Internet Message Format:
In the function form of your
sendmail
call, all lines are starting with white space and so are "unfolded" (concatenated) and you are trying to sendOther than our mind suggests,
smtplib
will not understand theTo:
andSubject:
headers any longer, because these names are only recognized at the beginning of a line. Insteadsmtplib
will assume a very long sender email address:This won't work and so comes your Exception.
The solution is simple: Just preserve the
message
string as it was before. This can be done by a function (as Zeeshan suggested) or right away in the source code:Now the unfolding does not occur and you send
which is what works and what was done by your old code.
Note that I was also preserving the empty line between headers and body to accommodate section 3.5 of the RFC (which is required) and put the include outside the function according to the Python style guide PEP-0008 (which is optional).
I'd like to help you with sending emails by advising the yagmail package (I'm the maintainer, sorry for the advertising, but I feel it can really help!).
The whole code for you would be:
Note that I provide defaults for all arguments, for example if you want to send to yourself, you can omit
TO
, if you don't want a subject, you can omit it also.Furthermore, the goal is also to make it really easy to attach html code or images (and other files).
Where you put contents you can do something like:
Wow, how easy it is to send attachments! This would take like 20 lines without yagmail ;)
Also, if you set it up once, you'll never have to enter the password again (and have it safely stored). In your case you can do something like:
which is much more concise!
I'd invite you to have a look at the github or install it directly with
pip install yagmail
.I recommend that you use the standard packages
email
andsmtplib
together to send email. Please look at the following example (reproduced from the Python documentation). Notice that if you follow this approach, the "simple" task is indeed simple, and the more complex tasks (like attaching binary objects or sending plain/HTML multipart messages) are accomplished very rapidly.For sending email to multiple destinations, you can also follow the example in the Python documentation:
As you can see, the header
To
in theMIMEText
object must be a string consisting of email addresses separated by commas. On the other hand, the second argument to thesendmail
function must be a list of strings (each string is an email address).So, if you have three email addresses:
person1@example.com
,person2@example.com
, andperson3@example.com
, you can do as follows (obvious sections omitted):the
"","".join(to)
part makes a single string out of the list, separated by commas.From your questions I gather that you have not gone through the Python tutorial - it is a MUST if you want to get anywhere in Python - the documentation is mostly excellent for the standard library.
Make sure you have granted permission for both Sender and Receiver to send email and receive email from Unknown sources(External Sources) in Email Account.
It's probably putting tabs into your message. Print out message before you pass it to sendMail.
Here is an example on Python
3.x
, much simpler than2.x
:call this function:
below may only for Chinese user:
If you use 126/163, 网易邮箱, you need to set"客户端授权密码", like below:
ref: https://stackoverflow.com/a/41470149/2803344 https://docs.python.org/3/library/email.examples.html#email-examples