I have put together a function send_email
[1] to send emails with support for plain-text and html messages. It works well, but I have an issue I don't quite know how to debug. My system has sendmail
as its MTA.
The function is called in a for loop, as follows:
for data in data_set:
subject, message = process(data) # Irrelevant stuff
send_email(subject, message, "fixed@email.address")
In the debug output of smtplib
[1] I see that all calls to send_email
completed successfully. The weird behavior is:
- If the
message
is "short" (I tested with a single line), all sent messages actually arrive tofixed@email.address
- If the
message
is "not short" (that is, the multiple lines I generate with the realprocess_data
function), only the first email does arrive, while the others don't, even though the debug output ofsmtplib
in [1] reports success for each and all of the emails. - If the
message
is equally "not short" but the destination address is different for each message, then all messages arrive to their intended destinations.
For the latter case, the for
loop would look like:
addresses = ["fixed@email.address", "fixed.2@email.address", ...]
for data, addr in zip(data_set, addresses):
subject, message = process(data) # Irrelevant stuff
send_email(subject, message, addr)
The intended behavior is of course different addresses for different data, but I'm concerned that not understanding why this happens might bite me in an unexpected way later on.
[1] My send mail function:
import smtplib
import socket
import getpass
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def send_email (subject, message, to, reply_to='', cc='', html_message=''):
COMMASPACE = ", "
user, host = get_user_and_host_names()
sender = '%s@%s' % (user, host)
receivers = make_address_list(to)
copies = make_address_list(cc)
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = COMMASPACE.join(receivers)
if reply_to:
msg.add_header('Reply-to', reply_to)
if len(copies):
msg.add_header('CC', COMMASPACE.join(copies))
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
if message:
msg.attach( MIMEText(message, 'plain'))
if html_message:
msg.attach( MIMEText(html_message, 'html'))
smtpObj = smtplib.SMTP('localhost')
smtpObj.set_debuglevel(1)
smtpObj.sendmail(sender, receivers, msg.as_string())
smtpObj.quit()
print "\nSuccessfully sent email to:", COMMASPACE.join(receivers)
def get_user_and_host_names():
user = getpass.getuser()
host = socket.gethostname()
return user, host
def make_address_list (addresses):
if isinstance(addresses, str):
receivers = addresses.replace(' ','').split(',')
elif isinstance(addresses, list):
receivers = addresses
return receivers