1

I am trying to send an email using SMTP via python. This is my code:

import smtplib
from email.mime.text import MIMEText

textfile='msg.txt'
you='ashwin@gmail.com'
me='ashwin@gmail.com'

fp = open(textfile, 'rb')
msg = MIMEText(fp.read())
fp.close()

# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
print "reached before s"
s = smtplib.SMTP('127.0.0.1',8000)
print "reached after s"
s.sendmail(me, [you], msg.as_string())
s.quit()

when I try and execute this code, "reached before s" is printed and then goes into an infinite loop or so, i.e. "reached after s" is not printed and the program is still running. This is code for the server:

import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

HandlerClass = SimpleHTTPRequestHandler
ServerClass  = BaseHTTPServer.HTTPServer
Protocol     = "HTTP/1.0"


if sys.argv[1:]:
    port = int(sys.argv[1])
else:
    port = 8000
server_address = ('127.0.0.1', port)



HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass)

sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
httpd.serve_forever()

can someone figure out what is wrong?

ashiwn
  • 25
  • 8
  • 2
    You don't have an SMTP server running on port `8000` in your machine (`127.0.0.1`) . You have a web server (HTTP). I answered a question along these lines here: http://stackoverflow.com/a/23047183/289011 Check it out. It might help. – Savir Jun 21 '15 at 15:25
  • @BorrajaX Probably [yagmail](https://github.com/kootenpv/yagmail) could be interesting to you as well, as per my answer :) – PascalVKooten Jun 21 '15 at 16:26

2 Answers2

0

I believe yagmail (disclaimer: I'm the maintainer) can be of great help to you.

Its goal is to make it easy to send emails with attachments.

import yagmail
yag = yagmail.SMTP('ashwin@gmail.com', 'yourpassword')
yag.send(to = 'ashwin@gmail.com', subject ='The contents of msg.txt', contents = 'msg.txt')

That's only three lines indeed.

Note that yagmail contents will try to load the string passed. If it cannot, it will send as text, if it can load it, it will attach it.

If you pass a list of strings, it will try to load each string as a file (or, again, just display the text).

Install with pip install yagmail or pip3 install yagmail for Python 3.

More info at github.

PascalVKooten
  • 20,643
  • 17
  • 103
  • 160
0

Here is a different approach that creates an email sender class with all the error handling taken care of:

import getpass
import smtplib

class EmailBot(object):
    # Gets the username and password and sets up the Gmail connection
    def __init__(self):
        self.username = \
            raw_input('Please enter your Gmail address and hit Enter: ')
        self.password = \
        getpass.getpass('Please enter the password for this email account and hit Enter: ')
        self.server = 'smtp.gmail.com'
        self.port = 587
        print 'Connecting to the server. Please wait a moment...'

        try:
            self.session = smtplib.SMTP(self.server, self.port)
            self.session.ehlo()  # Identifying ourself to the server
            self.session.starttls()  # Puts the SMTP connection in TLS mode. All SMTP commands that follow will be encrypted
            self.session.ehlo()
        except smtplib.socket.gaierror:
            print 'Error connecting. Please try running the program again later.'
            sys.exit() # The program will cleanly exit in such an error

        try:
            self.session.login(self.username, self.password)
            del self.password
        except smtplib.SMTPAuthenticationError:
            print 'Invalid username (%s) and/or password. Please try running the program again later.'\
                 % self.username
            sys.exit() # program will cleanly exit in such an error

        def send_message(self, subject, body):
            try:
                headers = ['From: ' + self.username, 'Subject: ' + subject,
                   'To: ' + self.username, 'MIME-Version: 1.0',
                   'Content-Type: text/html']
                headers = '\r\n'.join(headers)

                self.session.sendmail(self.username, self.username, headers + '''\r\r''' + body)
            except smtplib.socket.timeout:
                print 'Socket error while sending message. Please try running the program again later.'
                sys.exit() # Program cleanly exits
            except:
                print "Couldn't send message. Please try running the program again later."
                sys.exit() # Program cleanly exits

All you need to do is create an EmailBot instance and call the send_message method on it, with the appropriate details as inputs.

Andrew Winterbotham
  • 1,000
  • 7
  • 13