Tutorial: How to send
an email with Python

gmail

To code a script to send emails could be very useful for reporters. We could use it to create personalized alerts about any topic we want or to monitor our running scripts at a distance.

Note: To send yourself an email with a Python script, you need minimal knowledge of programming. I made this tutorial for people willing to learn. Once done with the tutorial, you should be able to use the code I wrote below!

#I Personalized alerts

By sending an email to yourself with the conditions of your choice, as coded in your script, you can create completely customized alerts.

You want to closely monitor an elected representative? Code a script that will check his Twitter and Facebook accounts every 10 minutes. If something new has been posted, an email will be automatically sent to you!

Your program could check three times a day all the transcript files of all the meetings he is supposed to attend. He said something? Tada! Your script could copy-paste his interventions in an email that you’ll receive a few seconds later!

Isn’t that great? Google Alerts are a joke compared to this!

#II Monitor you scripts at a distance

Another interesting use: to indicate when your scripts are done or when they stopped for an unexpected reason.

Some scripts can run for a very long time… If you are a web scraping addict, you know what I am talking about. If there is a lot of data to extract, your scripts will give your grey hair!

I remember a scraper I coded for one of my class, for my master’s degree. The goal was to extract all the data from the pro-active disclosure section of Public Works and Government Services Canada. Thousands of contracts, all on different webpages…! On top of that, I was regularly disconnected from their server. It took me days!

But when you are a reporter always running here and there, it’s impossible for you to stay close to your computer and check your beloved scripts! Hopefully, email updates could avoid you a lot of stress.

#III For a basic email

[ EDIT: Gmail made some security change change recently. You now have to allow “less secure apps” on your account. Otherwise, you won’t be able to connect to it with your python script. ]

There’s a native library in Python to send emails: smtplib. No need to install external librairies!

To send a basic email (without subject line), with a Gmail address, the code is fairly simple:

On line 2, it’s the parameters for the Gmail server. First, the server location (or its ip address), then the port to use. If you have an email address from another service, like Yahoo for example, you have to find the corresponding information.

On line 4, there’s a security function, needed to connect to the Gmail server. It will protect your password.

Donc forget to indicate your email address and your password on line 5.

The msg variable will contain your message and the last ligne will send it!

#IV For a more elaborate email

[ EDIT: Don’t forget to allow “less secure apps” on your Gmail account. ]

If you want to automatically send an email to the police for an interview each time there’s a press release regarding drug trafficking, you need to send more professional looking emails!

With the code below, you will send a clean email, with a sender, a receiver and a subject line.

To do this, you need two more modules: email.MIMEMultipart et email.MIMEText. They are part of the basic Python librairies. No need to install them.

Again, don’t forget to change the following lines:

  • Line 6 with your email address
  • Line 6 with the receiver’s email address
  • Line 11 with the email subject
  • Line 13 with your message
  • Line 18 with your password

#V To send an email with attachment

[ EDIT: Allow “less secure apps” on your Gmail account before running your script. ]

To have files attached to an email requires a more complicated code. While doing some research, I noticed almost everybody has a slightly different method to do this (my sources are all at the end of this article).

I tried to keep the code as simple as possible. However, many modules are still needed, as you can see below.

In summary, the essential step is to convert the file into a Base64 before sending it. My code works for text files, pdf files, images, audio files and video files!

On top of all the authentification needed, this time you also need to indicate:

  • The name of the file on line 21,
  • The path to the file on line 22.

It’s done! You have everything you need to add email sending to your scripts!

Follow me on Facebook, Twitter and LinkedIn to know when I will publish new articles!

How did I learn to send emails with Python? By reading all  of these really good articles:

– https://docs.python.org/2/library/smtplib.html 

– http://www.tutorialspoint.com/python/python_sending_email.htm

– http://en.wikibooks.org/wiki/Python_Programming/Email

– http://www.pythonforbeginners.com/code-snippets-source-code/using-python-to-send-email

– https://docs.python.org/2/library/email.mime.html

– https://docs.python.org/2/library/email-examples.html

– https://docs.python.org/2/library/email.html

– http://www.blog.pythonlibrary.org/2013/06/26/python-102-how-to-send-an-email-using-smtplib-email/

– http://www.smipple.net/snippet/Jimmyromanticde/gmail.py

131 thoughts on “Tutorial: How to send
an email with Python

  1. pythoncharmer

    Wasted 2 hours because I didn’t know this :
    There’s a native library in Python to send emails: smtplib. No need to install external librairies!
    😛

    Reply
  2. John

    You do realise that you have to enable less secure apps within your gmail settings to get this to work? Ain’t you got a more secure authentication method?

    Reply
      • Nick

        This just started happening within the past year. Google makes you change your settings, even with server.starttls(). I’m considering creating a dummy gmail account just for this, but if anybody knows a better way…..

        Reply
    • Mallikarjun Hangargi

      Google stopped the support for third party apps that call gmail authentication using username/password. It only supports Oauth 2.0 now. Through this authentication method, username and password are not stored , instead used once for authentication and further authorization take place through tokens issued by google to the third party app.

      This reduces the risk of compromise of passwords, when the third party apps are compromised for some reason.

      Reply
  3. Rik

    I get this message, it might be stupid, but what am I doing wrong? The attachment is in the root directory.

    Thanks!

    Rik

    root@raspberrypi:/home/pi# sudo python mail3.py
    Traceback (most recent call last):
    File “mail3.py”, line 21, in
    attachment = open(“/home/pi”, “rb”)
    IOError: [Errno 21] Is a directory: ‘/home/pi’

    Reply
  4. Larry

    Thanks for this tutorial.
    Can you please tell me the IDE you use to run this basic email .py script?
    I use Python 3 IDLE and plug in all the relevant info into your script and it does not work.
    I get error
    smtplib.SMTPAuthenticationError: (534, …….

    Reply
    • Thomas

      Hi,
      I am haveing this issue:

      Traceback (most recent call last):
      File “C:/Users/thogg/Desktop/myemail.py”, line 18, in
      server.login(fromaddr, “2511mable”)
      File “C:\Users\thogg\AppData\Local\Programs\Python\Python35-32\lib\smtplib.py”, line 729, in login
      raise last_exception
      File “C:\Users\thogg\AppData\Local\Programs\Python\Python35-32\lib\smtplib.py”, line 720, in login
      initial_response_ok=initial_response_ok)
      File “C:\Users\thogg\AppData\Local\Programs\Python\Python35-32\lib\smtplib.py”, line 641, in auth
      raise SMTPAuthenticationError(code, resp)
      smtplib.SMTPAuthenticationError: (535, b’5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials w190sm4608228wmd.14 – gsmtp’)

      Can you help?

      Reply
  5. k

    This is awesome! Thank you!

    I am getting:
    Traceback (most recent call last):
    File “naelshiab_email.py”, line 4, in
    from email.MIMEMultipart import MIMEMultipart
    ImportError: No module named ’email.MIMEMultipart’

    Huh?

    Reply
    • k

      this fixed it:

      import smtplib
      from email.mime.multipart import MIMEMultipart
      from email.mime.text import MIMEText

      instead of:

      import smtplib
      from email.MIMEMultipart import MIMEMultipart
      from email.MIMEText import MIMEText

      Reply
  6. Andrew Besag

    Your tutorial was extremely helpful to me as a newer python programmer! Very concise and broken down into parts that are easy to understand and progress through the different concepts. Thank you!

    Reply
  7. Corey Tokunaga

    Your tutorial was extremely helpful, but I am experiencing 1 problem. With my program that I’m using, I create a text file, then send that text file in an email. The file is being created fine, and the copy that I create has everything I need it to have. However the text file that is attached to the email is blank when I receive it. Any idea why this would be happening?

    Reply
    • Corey Tokunaga

      Just a bit of an update with my problem. The attachment is no longer blank. I think it just had to do with the size of the file and the system I’m using. If the file is large enough, then the file isn’t blank. However, now some of my file is getting deleted and I’m not receiving the full attachment in any situation. Any idea why this would happen?

      Reply
  8. Aalok

    error: [Errno 10013] An attempt was made to access a socket in a way forbidden by its access permissions
    I’m getting this error message.Could you please help?

    Reply
  9. Pratik

    Hey

    How can I send no-reply mails? I tried to set msg.add_header(‘reply-to’, None) but it didn’t work. Is it even possible from python script?

    Reply
  10. Nick

    Thanks for the tutorial Nael!

    Was wondering what tools you used to build your personal site. I really like the simplicity of this site.

    Do you use a static site generator like Jekyll or Pelican?

    Reply
  11. Behrgen Fletcher

    Awesome! The only problem is that I have an error message saying:

    ImportError: No module named MIMEMultiport

    And one saying:

    Module has no attribute “SMPT”

    I am not quite sure how to take this. Do I need to install something? I am on windows 8, and have Python 2.7.5.
    Any help would be greatly appreciated!

    Reply
  12. Ron Taylor

    Hello Nael
    Thank you for sharing your experience. I am a retired IT guy and have just started playing with Raspberry Pi’s (RPi) to monitor my Solar Electricity system. My RPi’s are located in an environment (high day time temps, high humidity etc) quite unfriendly to electronics and so monitoring of the system CPU temperature, Network Stats, access logs etc is essential.
    Your work has helped me to quickly develop a system send daily results on this data to my portable devices via email.
    Thank you.

    Reply
  13. Roberta

    Thank you so much, wasted hours installing and setting up different applications, with this tutorial got it working in couple of minutes!

    Reply
  14. Mike

    i have this error

    Traceback (most recent call last):
    File “C:\Users\mixalis\Desktop\mail2.py”, line 21, in
    attachment = open(“E:\paok\text.txt”, “rb”)
    OSError: [Errno 22] Invalid argument: ‘E:\\paok\text.txt’

    i use windows 10 , i cant figure out whats going on 🙁

    Reply
  15. Ankush Jamthikar

    Hello Sir,

    I am trying to send email using python but getting error massage as ‘gaierror: [Errno 11001] getaddrinfo failed’.I am using proxy settings of my college. Kindly help me in this regards.

    This is my code

    import smtplib

    try:
    sender = ‘username@gmail.com’
    receivers = [‘username@gmail.com’]

    message = “”” this message sending from python
    for testing purpose
    “””
    smtpObj = smtplib.SMTP_SSL(‘smtp.gmail.com’, port=465)
    smtpObj.ehlo()
    smtpObj.starttls()
    smtpObj.ehlo()
    smtpObj.login(‘ankushextc@gmail.com’,’pass’)
    smtpObj.sendmail(sender, receivers, message)
    smtpObj.quit()
    print “Successfully sent email”
    except smtplib.SMTPException,error:
    print str(error)
    print “Error: unable to send email”

    Reply
  16. Caleb

    I am getting an error saying “AttributeError: MIMEMultipart instance has no attribute ‘as_sting'”

    Cant find any evidence that others are getting the same error

    Reply
  17. Pingback: Programa da agenda telefonica com arquivos-texto | Prof. Franklin Marquezino

  18. George Senayah

    Can someone help me with python script for sending email attachment of motion detection images as and when detection takes place.

    Thank you.

    Reply
    • Ron

      server.sendmail(fromaddr, toaddrs, message)
      The toaddrs can be a list of destination email addresses. Do not use msg[‘bcc’] .

      Reply
  19. hian

    The tutorial was very good. But i would have enjoyed it more if in the end you had added one more section where you added an implementation with a class.

    Reply
  20. solomon mgunda

    Very nice explanation!!. I really appreciate it!!!.
    The script for sending email has worked fine. I’ve been looking for it from other websites. Unfortunately, their scripts were helpless due to poor explanation.
    Take *******
    Thanks for your assistance.

    Please, how do I send sms using python script?

    Reply
  21. Pingback: python smtp – Only I Learn

  22. Sucharita

    Hi…Great Tutorial.
    I am new to Python.Tried sending an email with an attachment but got stuck.
    Facing the following problem:

    attachment = open(“C:\\Users\\admin\\Desktop”, “rb”)
    IOError: [Errno 13] Permission denied: ‘C:\\Users\\admin\\Desktop’

    where am I going wrong.Any help would be appreciated. 🙂

    Reply
  23. ADITYA SAMADHIYA

    Okay I have no error, but there is no mail received, and the code kind of goes into endless wait and never terminates. What could be the problem and a possible solution?

    Reply
  24. Somu

    hi when i tried the first example am getting this error :
    Traceback (most recent call last):
    File “C:\Users\H134855\Desktop\client.py”, line 3, in
    server = smtplib.SMTP(‘smtp.gmail.com’, 587)
    File “C:\Users\H134855\AppData\Local\Programs\Python\Python35-32\lib\smtplib.p
    y”, line 251, in __init__
    (code, msg) = self.connect(host, port)
    File “C:\Users\H134855\AppData\Local\Programs\Python\Python35-32\lib\smtplib.p
    y”, line 335, in connect
    self.sock = self._get_socket(host, port, self.timeout)
    File “C:\Users\H134855\AppData\Local\Programs\Python\Python35-32\lib\smtplib.p
    y”, line 306, in _get_socket
    self.source_address)
    File “C:\Users\H134855\AppData\Local\Programs\Python\Python35-32\lib\socket.py
    “, line 711, in create_connection
    raise err
    File “C:\Users\H134855\AppData\Local\Programs\Python\Python35-32\lib\socket.py
    “, line 702, in create_connection
    sock.connect(sa)
    ConnectionRefusedError: [WinError 10061] No connection could be made because the
    target machine actively refused it

    Reply
  25. Eric N

    Wonderful tutorial. Best I’ve found that includes how to attach files, that’s always been a pain in my butt. However, I did have to add two lines of code to make the authentication work properly with hotmail (smtp.live.com), which was server.ehlo() before and after server.starttls(). I have no idea what they’re for, just saw them used in another tutorial out there and it fixed my issue.

    Thanks a ton!

    Reply
  26. Hamza

    Hi there,
    Thanks for the tutorial, very helpful indeed. I am now able to send images to my email but I cannot view them once i download them from email. How do i view them or how do i send images that would be viewable?

    Reply
  27. Rahul

    I tried to run this code, but I am getting error:

    Traceback (most recent call last):
    File “top”, line 12, in
    server = smtplib.SMTP(‘smtp.gmail.com’,587)
    File “/usr/lib64/python2.7/smtplib.py”, line 250, in __init__
    (code, msg) = self.connect(host, port)
    File “/usr/lib64/python2.7/smtplib.py”, line 310, in connect
    self.sock = self._get_socket(host, port, self.timeout)
    File “/usr/lib64/python2.7/smtplib.py”, line 285, in _get_socket
    return socket.create_connection((host, port), timeout)
    File “/usr/lib64/python2.7/socket.py”, line 553, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
    socket.gaierror: [Errno -2] Name or service not known

    Reply
    • KarmaAB

      I’m getting the same error as yours. It’s very strange as the same program worked flawlessly for some times. Now I can’t send any mail using smtlib as this errors allways come out.
      Did you solve it?

      File “mailg.py”, line 8, in
      smtpserver = smtplib.SMTP(“smtp.tim.it”, 587)
      File “/usr/lib/python2.7/smtplib.py”, line 249, in __init__
      (code, msg) = self.connect(host, port)
      File “/usr/lib/python2.7/smtplib.py”, line 309, in connect
      self.sock = self._get_socket(host, port, self.timeout)
      File “/usr/lib/python2.7/smtplib.py”, line 284, in _get_socket
      return socket.create_connection((port, host), timeout)
      File “/usr/lib/python2.7/socket.py”, line 553, in create_connection
      for res in getaddrinfo(host, port, 0, SOCK_STREAM):
      socket.gaierror: [Errno -2] Name or service not known

      Reply
  28. Punci

    Hey, I think your website might be having browser compatibility issues.
    When I look at your blog in Firefox, it looks fine but when opening in Internet Explorer, it has some overlapping.
    I just wanted to give you a quick heads up! Other
    then that, awesome blog!

    Reply
  29. Rishikesh Agrawani

    Great tutorial. I like and love Python programming. This is a part of my life. Today I’m enjoying this language. This tutorial is very-very useful for programmers.

    Reply
  30. Mathew

    I spent the last 5 hours trying to find out how to send a mail from a python script and then i reached this article ! Many many thanks !

    Reply
  31. Nanhui

    Great tutorial, learned a lot, saved a lot of time.
    Just a reminder: as I use Python 3.4, the import part looks like this:
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText

    Reply
  32. chowreddy

    Hi I am getting error

    Traceback (most recent call last):
    File “C:\Users\chowreddy\Desktop\ch.py”, line 26, in
    part.add_header(‘Content-Disposition’, “attachment; filename= ch.py” % filename)
    TypeError: not all arguments converted during string formatting
    [Finished in 3.2s with exit code 1]

    Reply
  33. chowreddy

    Hi , i have query daily will execute automatically fect the data that data and send to mail others , this code ok for me,sending email with attachment using python

    Reply
  34. Misganu

    wow! really wonder full tutorial thanks a lot. but I’ve some questions
    1) is it recipient address should be only gmail? because I didn’t get the message in yahoo inbox how ever when I run the code it seems right.
    2) how automatically send email when some thing is occur? for example in my case I want to send email to different persons when new file is added to directory (Folder)

    Reply
  35. Pingback: Creating a Python app for Destiny – Part 2: Emailing Xurs inventory. – Allyn H

  36. Ishan

    I am tring to write a python script to send emails with my company login pssword and have mentioned my company exchange server in script using smtp.
    As the approach mentioned in your tutorial but i am getting server login error

    Is it because of smtp
    Do i need to setup different protocol and port.

    I work for a telecom company.

    Reply
  37. Dennis

    Hi,
    in my installation with anaconda3 the imports has to be like this:
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText

    Don’t know if this is standard, but with the imports at the top it won’t be work on my system.
    Dennis

    Reply
  38. Arslan Rashid

    Hi.
    Im getting the following error:
    Traceback (most recent call last):
    File “Intruder_mail.py”, line 2, in
    import smtplib
    File “/usr/lib/python2.7/smtplib.py”, line 46, in
    import email.utils
    File “/home/pi/Desktop/email.py”, line 3, in
    from email.MIMEMultipart import MIMEMultipart
    ImportError: No module named MIMEMultipart

    I am usin python 2.7.9 on my raspberry 2

    Reply
  39. Pingback: continuing the email notifications | jamesorowe

  40. Barry

    Terrific tutorial. Total python newbie, although not a newbie programmer. The examples go right to the point the explanations clear. But the best part by far is the answer to “How did I learn to send emails with Python?”. Thanks for taking the time and effort to get this out there.

    Reply
  41. Mike

    Works great, I’m using a mobile phone as a wifi hotspot and would like to test if when it connects to the gmail server if it’s able to, at the moment the program falls over in a heap when there is no signal.

    Reply
  42. Kaleb

    Thanks a bunch! I tried multiple websites and tutorials trying to send an email with python and yours is the only one that worked. Thanks again!

    Reply
  43. Dirk Gruenhagen

    Well done, Nael.

    Your article helped me very much. Thenk you for this.

    There is only just a little inadequacy with your code starting in
    line 21 […] attachement = open( […]:
    You did not close it 🙂

    ‘attachment.close()’

    Thank you,

    Dirk

    Reply
  44. Alf

    Hello Nael Shiab,

    Thank you for the great tutorial.
    It worked for me.

    I just wonder how is this process faster than sending e -mail the normal way.
    (I am new to this so I would like to know the merits of this process).

    I would also love to know how to sort mails and organizing my mail box using python. If you have any tutorial for such, please point me to the right direction.

    Reply
  45. Ian Smith

    If you want this code to work with Python3 change the imports to:

    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    import smtplib

    Reply
  46. Lida

    This is a great tutorial. The only problem in my case that it only works with gmail server. I have a virtual private server (wpxxxxxxxx.mailout.server-he.de) , I have account on t-online.de server, they do not work. I thought that because of SSL, but I used smtplib.SMTP_SSL(“……….”) but it does not work.
    So I really would like to know the reason why. The main problem:

    >>> import smtplib
    >>> s=smtplib.SMTP(‘smtp.gmail.com’)
    >>> s.help()
    ‘2.0.0 https://www.google.com/search?btnI&q=RFC+5321 b188sm4817528wmh.6 – gsmtp’
    >>> s.quit()
    (221, ‘2.0.0 closing connection b188sm4817528wmh.6 – gsmtp’)
    so it works….

    but this:
    >>> s=smtplib.SMTP(‘smtpmail.t-online.de’)

    TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    >>>

    Reply
  47. Shayne

    Thank you for the tutorial. It really helped in understanding the modules. It is really easy to add the additional security though. Instead of using smtplib.SMTP simply use smtplib.SMTP_SSL. I tried it with my Google account and it works. I did have to get an authentication code from the Google Dashboard though since I have two step verification.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *