Capture debug output from Python smtplib
10,157
Solution 1
It can be done by redirecting stderr to a file:
import tempfile, smtplib, os, sys
# Find an available file descriptor
t = tempfile.TemporaryFile()
available_fd = t.fileno()
t.close()
# now make a copy of stderr
os.dup2(2,available_fd)
# Now create a new tempfile and make Python's stderr go to that file
t = tempfile.TemporaryFile()
os.dup2(t.fileno(),2)
# Now run the task that logs to stderr
s = smtplib.SMTP("mx10.comcast.com")
s.set_debuglevel(1)
s.sendmail("[email protected]",["[email protected]"],"""
from: [email protected]
to: [email protected]
subject: no such message
This message won't be delivered to anybody.
""")
# Grab the stderr from the temp file
sys.stderr.flush()
t.flush()
t.seek(0)
stderr_output = t.read()
t.close()
# Put back stderr
os.dup2(available_fd,2)
os.close(available_fd)
# Finally, demonstrate that we have the output:
print("STDERR:")
count = 0
for line in stderr_output.decode('utf-8').split("\n"):
count += 1
print("{:3} {}".format(count,line))
Solution 2
Study the error:
a = None
try:
s.sendmail("[email protected]" ["[email protected]"],"""
from: [email protected]
to: [email protected]
subject: no such message
This message won't be delivered to anybody.
""")
except smtplib.SMTPRecipientsRefused as e:
a = e
Now you can look at how to extract it:
a.args
({'[email protected]': (550, b'5.1.1 Recipient address rejected: {Gateway}')},)
a.args[0]['[email protected]'][1]
b'5.1.1 Recipient address rejected: {Gateway}'
And here is your message!
So to extract it:
message = None
try:
s.sendmail("...")
except smtplib.SMTPException as e:
message = e.args[0]['[email protected]'][1]
Comments
-
Ami almost 2 years
How do I capture the debug output from the Python smtplib library?
Here is my test program:
import smtplib s = smtplib.SMTP("mx10.comcast.com") s.set_debuglevel(1) s.sendmail("[email protected]",["[email protected]"],""" from: [email protected] to: [email protected] subject: no such message This message won't be delivered to anybody. """)
Here is the output:
send: 'ehlo dance.local\r\n' reply: '250-mx10.comcast.com says EHLO to 129.6.220.67:57015\r\n' reply: '250-SIZE 40000000\r\n' reply: '250-PIPELINING\r\n' reply: '250-ENHANCEDSTATUSCODES\r\n' reply: '250-8BITMIME\r\n' reply: '250 XXXXXXXA\r\n' reply: retcode (250); Msg: mx10.comcast.com says EHLO to 129.6.220.67:57015 SIZE 40000000 PIPELINING ENHANCEDSTATUSCODES 8BITMIME XXXXXXXA send: 'mail FROM:<[email protected]> size=137\r\n' reply: '250 2.0.0 MAIL FROM accepted\r\n' reply: retcode (250); Msg: 2.0.0 MAIL FROM accepted send: 'rcpt TO:<[email protected]>\r\n' reply: '550 5.1.1 Recipient address rejected: {Gateway}\r\n' reply: retcode (550); Msg: 5.1.1 Recipient address rejected: {Gateway} send: 'rset\r\n' reply: '250 2.0.0 RSET OK\r\n' reply: retcode (250); Msg: 2.0.0 RSET OK Traceback (most recent call last): File "/Users/simsong/x.py", line 11, in <module> """) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/smtplib.py", line 742, in sendmail raise SMTPRecipientsRefused(senderrs) smtplib.SMTPRecipientsRefused: {'[email protected]': (550, '5.1.1 Recipient address rejected: {Gateway}')}
I want the output in a variable,
output
. Specifically, I want all of the lines that begin withsend:
andreply:
.