In this tutorial we will see how to send email using Python. We will need two python libraries for the same, smtplib will be used for making a host for sending email it will also handle routing of email between different servers. email package allows us to use HTML and other kind of text in our email, we can also use attachments using the same.
For sending email we will first need to create a local SMTP (Simple Mail Transfer Protocol) server. This can be done by creating an SMTP object from smtplib. Connections from SMTP server are considered as less secure by Gmail so you need to first allow less secure apps from setting for this to work. But this will also allow other less secure apps to use your Gmail so it is highly recommended that you create a new gmail account for this purpose.
Python Send Email Using SMTP
Let us first create an SMTP object for sending email.
import smtplib server = smtplib.SMTP('smtp.gmail.com:587') server.starttls()
Here smtp.gmail.com is our host address and 587 is port number, here we are using the TLS (Transport Layer Security) encryption which will create an unsecured connection which is being encrypted using .starttls() later. If we use SSL (Secured Socket Layer) Protocol then we should use port 485. We will be sticking with TLS protocol in this tutorial.
Now our local server is set up and we are ready to create the body of our email. We will send MIME (Multipurpose Internet Mail Extension) Multipart email, these are handled by the email.mime module of email package.
Documentation for the email mime module can be found here. We will start by first creating a MIMEMultipart object which is basically an email object. It will have all the attributes like From, To, Subject, Email body and other email attributes. We will fill all these fields and we are good to go. The text which is going to present on must be converted into a MIME object which is done using the email.mime.text module.
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import smtplib # creating a Multipart Object for email msg = MIMEMultipart() msg['From'] = "sender@gmail.com" msg['To'] = "reciever@gmail.com" msg['Subject'] = "Python Email"
The above code will set the from, to and subject field in our email. For the body of email we will create a string and convert that into MIMEText object and then attach that to MIMEMultipart object.
message = "This email is sent using python." msg.attach(MIMEText(message,'plain'))
The MIMEText takes two arguments first is the text and the second is the subtype of that text, here we are having plain text therefore our subtype is plain.
Only part now remaining is to login into the SMTP server and send the mail. We can login using the from field of msg as we are going to send our msg from that email address.
Password = "Password" server.login(msg['From'],Password) server.sendmail(msg['From'],msg['To'],msg.as_string()) .sendmail will now send our msg from msg['From'] to msg['To']
The complete is as below :
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText server = smtplib.SMTP('smtp.gmail.com:587') server.starttls() msg = MIMEMultipart() msg['From'] = "sender@gmail.com" msg['To'] = "reciever@gmail.com" msg['Subject'] = "Python Email" message = "This email is sent using python." msg.attach(MIMEText(message,'plain')) Password = "Password" server.login(msg['From'],Password) server.sendmail(msg['From'],msg['To'],msg.as_string()) print("Message sent from " + msg['From'] + " to " + msg['To'])
Note : Sometimes specific ports are blocked on public internet so if you face TimeourError then try changing your internet connection.
Till now we have seen how to set up local server and send plain messages. Let us now move to how we can send different styles messages and use attachments. Now we will see how can attach html content in email.
Everything else will remain the same we just need to change the message string to a HTML text and while converting the string to MIMEText object we should specify that the subtype as html. We can attach multiple time to our Multipart object.
message = """ <html> <body> <p> <b> Hello Everyone </b>,<br> How are you all?<br> <a href="http://thecrazyprogrammer.com">Crazy Programmer</a> has good Python tutorials. </p> </body> </html> """ message2 = "This is the second attachment" msg.attach(MIMEText(message,'html')) msg.attach(MIMEText(message2,'plain'))
Now we will move to attachments how attachments can be done in email.
Attaching Image:
We should first open our image using in python convert that into an MIMEImage object and then attach it to MIMEMultipart object.
from email.mime.image import MIMEImage filepath = 'path' fp = open(filepath,'rb') filecontent = fp.read() fp.close() msg.attach(MIMEImage(filecontent))
Make sure that you add extension of image while is being used in path of image. The above code will attach image to our mail.
Attaching PDF:
from email.mime.application import MIMEApplication fp = open('path','rb') filecontent = fp.read() att = MIMEApplication(filecontent,_subtype="pdf") fp.close() att.add_header('Content-Disposition','attachment',filename='test.pdf') msg.attach(att)
Let us now see a code having all the above functionalities:
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication from email.mime.image import MIMEImage server = smtplib.SMTP('smtp.gmail.com:587') server.starttls() msg = MIMEMultipart() msg['From'] = "sender@gmail.com" msg['To'] = "reciever@gmail.com" msg['Subject'] = "Python Email" message = "This email is sent using python." msg.attach(MIMEText(message,'plain')) htmlMessage = """ <html> <body> <p> <b> Hello Everyone </b>,<br> How are you all?<br> <a href="http://thecrazyprogrammer.com">Crazy Programmer</a> has good Python tutorials. </p> </body> </html> """ msg.attach(MIMEText(htmlMessage,'html')) filepath = 'path' fp = open(filepath,'rb') filecontent = fp.read() fp.close() msg.attach(MIMEImage(filecontent)) fpPDF = open('path','rb') pdfFilecontent = fpPDF.read() att = MIMEApplication(pdfFilecontent,_subtype="pdf") fpPDF.close() att.add_header('Content-Disposition','attachment',filename='test.pdf') msg.attach(att) Password = "Password" server.login(msg['From'],Password) server.sendmail(msg['From'],msg['To'],msg.as_string()) print("Message sent from " + msg['From'] + " to " + msg['To'])
Sending Personalized Emails:
Till now we have seen sending general emails to receptionist but this is not of much use, In most of the real case scenario we will need to send personalized emails. We can do this easily just by changing a few things in our code. We will first save all the information into a csv (Comma Separated Values) file.
For example here, suppose we have a .csv file containing name, email address, marks and grades of students and we want to send emails to all of them containing their marks and grades. We will first create our msg and then we can format it using the .format method in python before sending the mail.
Import csv att = "Hi {name}, your marks are {marks} and your grade is {grade}" with open('list.csv') as file : reader = csv.reader(file) # Skipping the header row from csv file next(reader) for name, email, grade, marks in reader : msg = MIMEMultipart() msg['From'] = "shubhampimple161998@gmail.com" str = att.format(name = name, marks = marks, grade = grade) msg.attach(MIMEText(str,'plain')) server.sendmail(msg['From'],email,msg.as_string()) print("Email Sent") C
Here att.format is formatting our message by taking values from the csv file. This way we can easily send personalized messages to a list of receptionists.
For more information on MIMEText, MIMEImage, MIMEMultipart and functions .sendmail(), .attach() you can visit the documentation here.
Comment down below if you have queries related to python send email using smtp.