Я собрал функцию send_email
[1] для отправки электронных писем с поддержкой текстовых и HTML-сообщений. Это работает хорошо, но у меня есть проблема, которую я не совсем знаю, как отлаживать. Моя система имеет sendmail
в качестве MTA.
Функция вызывается в цикле for следующим образом:
for data in data_set:
subject, message = process(data) # Irrelevant stuff
send_email(subject, message, "[email protected]")
В выводе отладки smtplib
[1] я вижу, что все вызовы send_email
выполнены успешно. Странное поведение:
- Если
message
"короткий" (я тестировал с одной строкой), все отправленные сообщения фактически поступают на[email protected]
- Если
message
"не короткое" (то есть несколько строк, которые я генерирую с помощью настоящей функцииprocess_data
), приходит только первое электронное письмо, а остальные нет, несмотря на то, что вывод отладки изsmtplib
в [1] сообщает об успешном завершении каждого письма. - Если
message
в равной степени "не короткий" но адрес назначения разный для каждого сообщения, тогда все сообщения доставляются по назначению.
В последнем случае цикл for
будет выглядеть так:
addresses = ["[email protected]", "[email protected]", ...]
for data, addr in zip(data_set, addresses):
subject, message = process(data) # Irrelevant stuff
send_email(subject, message, addr)
Предполагаемое поведение, конечно, разные адреса для разных данных, но я обеспокоен тем, что непонимание того, почему это происходит, может позже неожиданно укусить меня.
[1] Моя функция отправки почты:
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