Use Python to send email using SMTP
Use Python to send emails
In this tutorial, we will learn to use python to send emails. If you are new to python, you can see our beginner’s series. In case you are having trouble installing Python, you can see our posts on installing python on MacOS and Windows.
We will start with sending plain email using python and then learn to send advanced automated emails, HTML emails, emails with attachments etc. In this tutorial, we will be using gmail to send email via python, which is the most common email service used. However, you can use any other email service.(You will have to use slightly different setting in that case.)
Open your gmail account. If you are not using
2-Step Verification, you will have to allow less secure apps from this link.
However, if you are using 2-Step Verification (which I highly recommend), you need to create app password for your account for this project from here. You can learn to create app passwords from google’s official documentation.
We do not want to hard code our username and password, so we will be using environment variable to set them. Open the .bash_profile of your MacOS and save the email and password (or app password in case of 2-step verification) as under:-
$ nano .bash_profile
# .bash_profile
export EMAIL_USER="your_email"
export PASSWORD="your_password"
$ source .bash_profile
Sending simple email using python
Now create a file called ‘python_send_email.py’ and import smtplib and write down the following code:-
# python_send_email.py
import os
import smtplib
EMAIL = os.environ.get('EMAIL_USER')
PASSWORD = os.environ.get('PASSWORD')
with smtplib.SMTP('smtp.gmail.com', 587) as smtp:
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(EMAIL, PASSWORD)
subject = 'Python Send Email'
body = 'This email is sent using python'
message = f'Subject:{subject}\n\n{body}'
smtp.sendmail(EMAIL, EMAIL, message)
Let me quickly go through each step.
We have used os to use environment variables where we have saved our username and password.
Then we have used the context manager, so that the connection ends by itself after the script is complete.
Then we identified ourselves using smtp.ehlo(), then we put it in the connection mode using smtp.starttls() and logged in using smtp.login().
Finally, we will draft the email by adding subject, body, message and send it using smtp.sendmail(sender, receipient, message). Running the script will send the simple email to the user.
Sending email using local debugging server
While we are testing/learning, it could be frustrating to use real email, so we will start local debugging server using the following command. When we will run this, all the future emails which we will send using our script will be displayed on the terminal.
$ python -m smtpd -c DebuggingServer -n localhost:1025
Now, we will have to make following changes to python_send_email.py :-
# python_send_email.py
# with smtplib.SMTP('smtp.gmail.com', 587) as smtp:
with smtplib.SMTP('localhost', 1025) as smtp: #add this and comment out the rest
# smtp.ehlo()
# smtp.starttls()
# smtp.ehlo()
# smtp.login(EMAIL, PASSWORD)
Now if we will run our python_send_email.py, it will be displayed in the terminal.
Cleaning it up
Instead of calling the server using smtp.ehlo() we will be creating a SSL connection from the very beginning using smptlib.SMTP_SSL and instead of port 587, we will use port 465. Now, we will be taking advantage of EmailMessage class of email.message to create a message and finally smtp.send_message() to send that message. The modified code is as under:-
# python_send_email.py
import os
import smtplib
from email.message import EmailMessage #new
EMAIL = os.environ.get('EMAIL_USER')
PASSWORD = os.environ.get('PASSWORD')
message = EmailMessage()
message['Subject'] = 'Python Send Email'
message['From'] = EMAIL
message['To'] = EMAIL
message.set_content('This email is sent using python.')
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(EMAIL, PASSWORD)
smtp.send_message(message)
Python - send email with attachment
Now we will be sending the emails with attachment. In order to send an image we will be using imghdr to find out the type of the image. Now place the image python_send_email.jpg in the same directory as the script python_send_email.py and change the code as under:
# python_send_email.py
import imghdr # new
with open('python_send_email.jpg', 'rb') as f:
file_data = f.read()
file_type = imghdr.what(f.name)
file_name = f.name
message.add_attachment(file_data, maintype='image', subtype=file_type, filename=file_name)
Written with StackEdit.