SMTP (Simple Mail Transfer Protocol) is a set of rules for transferring email from source to destination, controlling the way mail is relayed.
Python’s smtplib provides a very convenient way to send emails. It provides a simple encapsulation of the SMTP protocol.
The syntax for creating an SMTP object in Python is as follows:
import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
Parameter description:
- host: SMTP server host. You can specify the host’s IP address or domain name such as: runoob.com. This is an optional parameter.
- port: If you provide the host parameter, you need to specify the port number used by the SMTP service. Generally, the SMTP port number is 25.
- local_hostname: If SMTP is on your local machine, you only need to specify the server address as localhost.
The Python SMTP object uses the sendmail method to send emails. The syntax is as follows:
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]
Parameter description:
- from_addr: The sender’s email address.
- to_addrs: A list of strings, the email addresses to send to.
- msg: The message to send
Note the third parameter, msg, which is a string representing the email. We know that an email generally consists of the subject, sender, recipient, email content, attachments, etc. When sending an email, you need to pay attention to the format of msg. This format is defined by the SMTP protocol.
The following is a simple example of sending an email using Python:
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender = '[email protected]'
receivers = ['[email protected]'] # Recipient email, can be set to your QQ mailbox or other mailbox
# Three parameters: the first is the text content, the second 'plain' sets the text format, the third 'utf-8' sets the encoding
message = MIMEText('Python email sending test...', 'plain', 'utf-8')
message['From'] = Header("Runoob Tutorial", 'utf-8') # Sender
message['To'] = Header("Test", 'utf-8') # Recipient
subject = 'Python SMTP Email Test'
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, message.as_string())
print ("Email sent successfully")
except smtplib.SMTPException:
print ("Error: Unable to send email")
We use triple quotes to set the email information. A standard email requires three header lines: From, To, and Subject, each separated by a blank line.
We connect to the SMTP access by instantiating the SMTP object smtpObj of the smtplib module and use the sendmail method to send the message.
After executing the above program, if you have sendmail installed on your local machine, it will output:
$ python3 test.py
Email sent successfully
Check your inbox (usually in the spam folder), and you can see the email information:

If you do not have sendmail access on your local machine, you can also use SMTP access from other service providers (QQ, NetEase, Google, etc.).
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# Third-party SMTP service
mail_host="smtp.XXX.com" # Set the server
mail_user="XXXX" # Username
mail_pass="XXXXXX" # Password
sender = '[email protected]'
receivers = ['[email protected]'] # Recipient email, can be set to your QQ mailbox or other mailbox
message = MIMEText('Python email sending test...', 'plain', 'utf-8')
message['From'] = Header("Runoob Tutorial", 'utf-8')
message['To'] = Header("Test", 'utf-8')
subject = 'Python SMTP Email Test'
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP()
smtpObj.connect(mail_host, 25) # 25 is the SMTP port number
smtpObj.login(mail_user,mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print ("Email sent successfully")
except smtplib.SMTPException:
print ("Error: Unable to send email")
The difference between sending HTML-formatted email and plain text email in Python is that the _subtype in MIMEText is set to html. The specific code is as follows:
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender = '[email protected]'
receivers = ['[email protected]'] # Recipient email, can be set to your QQ mailbox or other mailbox
mail_msg = """
<p>Python email sending test...</p>
<p><a href="http://www.runoob.com">This is a link</a></p>
"""
message = MIMEText(mail_msg, 'html', 'utf-8')
message['From'] = Header("Runoob Tutorial", 'utf-8')
message['To'] = Header("Test", 'utf-8')
subject = 'Python SMTP Email Test'
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, message.as_string())
print ("Email sent successfully")
except smtplib.SMTPException:
print ("Error: Unable to send email")
After executing the above program, if you have sendmail installed on your local machine, it will output:
$ python3 test.py
Email sent successfully
Check your inbox (usually in the spam folder), and you can see the email information:

To send an email with attachments, first create a MIMEMultipart() instance, then construct the attachments. If there are multiple attachments, they can be constructed in sequence. Finally, use smtplib.smtp to send.
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
sender = '[email protected]'
receivers = ['[email protected]'] # Recipient email, can be set to your QQ mailbox or other mailbox
# Create an instance with attachments
message = MIMEMultipart()
message['From'] = Header("Runoob Tutorial", 'utf-8')
message['To'] = Header("Test", 'utf-8')
subject = 'Python SMTP Email Test'
message['Subject'] = Header(subject, 'utf-8')
# Email body content
message.attach(MIMEText('This is the Runoob Tutorial Python email sending test...', 'plain', 'utf-8'))
# Construct attachment 1, send the test.txt file in the current directory
att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# The filename here can be anything; whatever name is written will be displayed in the email
att1["Content-Disposition"] = 'attachment; filename="test.txt"'
message.attach(att1)
# Construct attachment 2, send the runoob.txt file in the current directory
att2 = MIMEText(open('runoob.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="runoob.txt"'
message.attach(att2)
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, message.as_string())
print ("Email sent successfully")
except smtplib.SMTPException:
print ("Error: Unable to send email")
$ python3 test.py
Email sent successfully
Check your inbox (usually in the spam folder), and you can see the email information:

In the HTML text of an email, adding external links through general email service providers is generally ineffective. The correct way to add images is shown in the following example:
#!/usr/bin/python3
import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
sender = '[email protected]'
receivers = ['[email protected]'] # Recipient email, can be set to your QQ mailbox or other mailbox
msgRoot = MIMEMultipart('related')
msgRoot['From'] = Header("Runoob Tutorial", 'utf-8')
msgRoot['To'] = Header("Test", 'utf-8')
subject = 'Python SMTP Email Test'
msgRoot['Subject'] = Header(subject, 'utf-8')
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)
mail_msg = """
<p>Python email sending test...</p>
<p><a href="http://www.runoob.com">Runoob Tutorial Link</a></p>
<p>Image demonstration:</p>
<p><img src="cid:image1"></p>
"""
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))
# Specify the image in the current directory
fp = open('test.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
# Define the image ID, referenced in the HTML text
msgImage.add_header('Content-ID', '<image1>')
msgRoot.attach(msgImage)
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, msgRoot.as_string())
print ("Email sent successfully")
except smtplib.SMTPException:
print ("Error: Unable to send email")
$ python3 test.py
Email sent successfully
Check your inbox (if in the spam folder, you may need to move it to the inbox for proper display), and you can see the email information:

Here we use QQ Mail’s SMTP service (you can also use 163, Gmail, etc.). The following configuration is required:

QQ Mail generates an authorization code to set the password:

QQ Mail SMTP server address: smtp.qq.com, SSL port: 465.
In the following example, you need to modify: the sender’s email (your QQ email), password, and recipient’s email (can be sent to yourself).
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
my_sender='[email protected]' # Sender's email account
my_pass = 'xxxxxxxxxx' # Sender's email password
my_user='[email protected]' # Recipient's email account, I'm sending to myself
def mail():
ret=True
try:
msg=MIMEText('Fill in the email content','plain','utf-8')
msg['From']=formataddr(["FromRunoob",my_sender]) # Corresponds to sender's email nickname and sender's email account in parentheses
msg['To']=formataddr(["FK",my_user]) # Corresponds to recipient's email nickname and recipient's email account in parentheses
msg['Subject']="Runoob Tutorial email sending test" # Email subject, also known as the title
server=smtplib.SMTP_SSL("smtp.qq.com", 465) # SMTP server in the sender's email, port is 25
server.login(my_sender, my_pass) # Corresponds to sender's email account and email password in parentheses
server.sendmail(my_sender,[my_user,],msg.as_string()) # Corresponds to sender's email account, recipient's email account, and sent email in parentheses
server.quit() # Close the connection
except Exception: # If the statements in try are not executed, the following ret=False will be executed
ret=False
return ret
ret=mail()
if ret:
print("Email sent successfully")
else:
print("Email sending failed")
$ python test.py
Email sent successfully
After successful sending, log in to the recipient’s email to view:

For more content, please refer to: https://docs.python.org/3/library/email-examples.html.