how to send mail in python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# smtplib -> https://docs.python.org/3/library/smtplib.html
import smtplib
# contextlib -> https://docs.python.org/3/library/contextlib.html
from contextlib import contextmanager
# email -> https://docs.python.org/3/library/email.examples.html#email-examples
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
SMTP_SERVERS = ['your smtp servers']
def _format_addr(s):
''' format the address
'''
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
def generate_mail(from_addr,
to_addr,
cc_addr,
subject,
body,
mime_type='plain'):
'''plain/text text/html
'''
msg = MIMEText(body, mime_type, 'utf-8')
msg['From'] = _format_addr(from_addr)
msg['To'] = ",".join([_format_addr(x) for x in to_addr])
msg['Cc'] = ",".join([_format_addr(x) for x in cc_addr])
msg['Subject'] = Header(subject, 'utf-8').encode()
return msg
def send_mail(from_addr, to_addr, cc_addr, subject, body, mime_type='plain'):
server = smtplib.SMTP(SMTP_SERVERS[0], 25)
server.set_debuglevel(1)
msg = generate_mail(from_addr, to_addr, cc_addr, subject, body, mime_type)
server.sendmail(from_addr, to_addr + cc_addr, msg.as_string())
server.quit()
# 1. to implement context manager, use decorator @contextmanager
# and yield
@contextmanager
def send_mail_context():
'''context manager
with send_mail_context()
'''
try:
# 1 doing work BEFORE the code goes into with block
print('before yield')
server = smtplib.SMTP(SMTP_SERVERS[0], 25)
# 2 yield back to with/caller
yield server
except Exception as e:
print(e)
finally:
# 4. doing cleanup work
server.quit()
print('in finally')
# 2 implement contextmanager with class
class SMTPCT(object):
'''
1. override __enter__ __exit__
2. in __enter__, return value
'''
def __init__(self):
self.smtp_server = None
def __enter__(self):
# 1 doing work BEFORE the code goes into with block
print('in enter')
self.smtp_server = smtplib.SMTP(SMTP_SERVERS[0], 25)
# 2 return back to with/caller
return self.smtp_server
def __exit__(self, type, value, traceback):
# 4. doing cleanup work
print('in exit')
self.smtp_server.quit()
def send_mail_in_context_class(from_addr,
to_addr,
cc_addr,
subject,
body,
mime_type='plain'):
msg = generate_mail(from_addr, to_addr, cc_addr, subject, body, mime_type)
with SMTPCT() as server:
# 3. do the actual job
server.sendmail(from_addr, to_addr + cc_addr, msg.as_string())
print('in with block')
print('sent')
def send_mail_in_context_yield(from_addr,
to_addr,
cc_addr,
subject,
body,
mime_type='plain'):
msg = generate_mail(from_addr, to_addr, cc_addr, subject, body, mime_type)
with send_mail_context() as server:
# 3. do the actual job
server.sendmail(from_addr, to_addr + cc_addr, msg.as_string())
print('in with block')
print('sent')
if __name__ == '__main__':
pass
# 1. send mail with contextmanager implemented in class
# send_mail_in_context_class('your_from_address',
# ['to_address'], [],
# 'test', 'this is test mail')
# 2. send mail with contextmanager implemented with yield
# send_mail_in_context_yield('your_from_address',
# ['to_addr'], [],
# 'test', 'this is test mail')