Sending mail from Python using SMTP

I'm using the following method to send mail from Python using SMTP. Is it the right method to use or are there gotchas I'm missing ?

from smtplib import SMTP
import datetime

debuglevel = 0

smtp = SMTP()
smtp.set_debuglevel(debuglevel)
smtp.connect('YOUR.MAIL.SERVER', 26)
smtp.login('USERNAME@DOMAIN', 'PASSWORD')

from_addr = "John Doe <john@doe.net>"
to_addr = "foo@bar.com"

subj = "hello"
date = datetime.datetime.now().strftime( "%d/%m/%Y %H:%M" )

message_text = "Hello\nThis is a mail from your server\n\nBye\n"

msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n\n%s" 
        % ( from_addr, to_addr, subj, date, message_text )

smtp.sendmail(from_addr, to_addr, msg)
smtp.quit()


Asked by: Charlie350 | Posted: 01-10-2021






Answer 1

The script I use is quite similar; I post it here as an example of how to use the email.* modules to generate MIME messages; so this script can be easily modified to attach pictures, etc.

I rely on my ISP to add the date time header.

My ISP requires me to use a secure smtp connection to send mail, I rely on the smtplib module (downloadable at http://www1.cs.columbia.edu/~db2501/ssmtplib.py)

As in your script, the username and password, (given dummy values below), used to authenticate on the SMTP server, are in plain text in the source. This is a security weakness; but the best alternative depends on how careful you need (want?) to be about protecting these.

=======================================

#! /usr/local/bin/python


SMTPserver = 'smtp.att.yahoo.com'
sender =     'me@my_email_domain.net'
destination = ['recipient@her_email_domain.com']

USERNAME = "USER_NAME_FOR_INTERNET_SERVICE_PROVIDER"
PASSWORD = "PASSWORD_INTERNET_SERVICE_PROVIDER"

# typical values for text_subtype are plain, html, xml
text_subtype = 'plain'


content="""\
Test message
"""

subject="Sent from Python"

import sys
import os
import re

from smtplib import SMTP_SSL as SMTP       # this invokes the secure SMTP protocol (port 465, uses SSL)
# from smtplib import SMTP                  # use this for standard SMTP protocol   (port 25, no encryption)

# old version
# from email.MIMEText import MIMEText
from email.mime.text import MIMEText

try:
    msg = MIMEText(content, text_subtype)
    msg['Subject']=       subject
    msg['From']   = sender # some SMTP servers will do this automatically, not all

    conn = SMTP(SMTPserver)
    conn.set_debuglevel(False)
    conn.login(USERNAME, PASSWORD)
    try:
        conn.sendmail(sender, destination, msg.as_string())
    finally:
        conn.quit()

except:
    sys.exit( "mail failed; %s" % "CUSTOM_ERROR" ) # give an error message

Answered by: Adrian739 | Posted: 02-11-2021



Answer 2

The method I commonly use...not much different but a little bit

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

msg = MIMEMultipart()
msg['From'] = 'me@gmail.com'
msg['To'] = 'you@gmail.com'
msg['Subject'] = 'simple email in python'
message = 'here is the email'
msg.attach(MIMEText(message))

mailserver = smtplib.SMTP('smtp.gmail.com',587)
# identify ourselves to smtp gmail client
mailserver.ehlo()
# secure our email with tls encryption
mailserver.starttls()
# re-identify ourselves as an encrypted connection
mailserver.ehlo()
mailserver.login('me@gmail.com', 'mypassword')

mailserver.sendmail('me@gmail.com','you@gmail.com',msg.as_string())

mailserver.quit()

That's it

Answered by: Sienna932 | Posted: 02-11-2021



Answer 3

Also if you want to do smtp auth with TLS as opposed to SSL then you just have to change the port (use 587) and do smtp.starttls(). This worked for me:

...
smtp.connect('YOUR.MAIL.SERVER', 587)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login('USERNAME@DOMAIN', 'PASSWORD')
...

Answered by: Ryan911 | Posted: 02-11-2021



Answer 4

Make sure you don't have any firewalls blocking SMTP. The first time I tried to send an email, it was blocked both by Windows Firewall and McAfee - took forever to find them both.

Answered by: Grace241 | Posted: 02-11-2021



Answer 5

What about this?

import smtplib

SERVER = "localhost"

FROM = "sender@example.com"
TO = ["user@example.com"] # must be a list

SUBJECT = "Hello!"

TEXT = "This message was sent with Python's smtplib."

# Prepare actual message

message = """\
From: %s
To: %s
Subject: %s

%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)

# Send the mail

server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()

Answered by: Lenny103 | Posted: 02-11-2021



Answer 6

The main gotcha I see is that you're not handling any errors: .login() and .sendmail() both have documented exceptions that they can throw, and it seems like .connect() must have some way to indicate that it was unable to connect - probably an exception thrown by the underlying socket code.

Answered by: Edgar536 | Posted: 02-11-2021



Answer 7

following code is working fine for me:

import smtplib
 
to = 'mkyong2002@yahoo.com'
gmail_user = 'mkyong2002@gmail.com'
gmail_pwd = 'yourpassword'
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
smtpserver.login(gmail_user, gmail_pwd)
header = 'To:' + to + '\n' + 'From: ' + gmail_user + '\n' + 'Subject:testing \n'
print header
msg = header + '\n this is test msg from mkyong.com \n\n'
smtpserver.sendmail(gmail_user, to, msg)
print 'done!'
smtpserver.quit()

Ref: http://www.mkyong.com/python/how-do-send-email-in-python-via-smtplib/

Answered by: Richard935 | Posted: 02-11-2021



Answer 8

The example code which i did for send mail using SMTP.

import smtplib, ssl

smtp_server = "smtp.gmail.com"
port = 587  # For starttls
sender_email = "sender@email"
receiver_email = "receiver@email"
password = "<your password here>"
message = """ Subject: Hi there

This message is sent from Python."""


# Create a secure SSL context
context = ssl.create_default_context()

# Try to log in to server and send email
server = smtplib.SMTP(smtp_server,port)

try:
    server.ehlo() # Can be omitted
    server.starttls(context=context) # Secure the connection
    server.ehlo() # Can be omitted
    server.login(sender_email, password)
    server.sendmail(sender_email, receiver_email, message)
except Exception as e:
    # Print any error messages to stdout
    print(e)
finally:
    server.quit()

Answered by: Tess183 | Posted: 02-11-2021



Answer 9

You should make sure you format the date in the correct format - RFC2822.

Answered by: Ned570 | Posted: 02-11-2021



Answer 10

See all those lenghty answers? Please allow me to self promote by doing it all in a couple of lines.

Import and Connect:

import yagmail
yag = yagmail.SMTP('john@doe.net', host = 'YOUR.MAIL.SERVER', port = 26)

Then it is just a one-liner:

yag.send('foo@bar.com', 'hello', 'Hello\nThis is a mail from your server\n\nBye\n')

It will actually close when it goes out of scope (or can be closed manually). Furthermore, it will allow you to register your username in your keyring such that you do not have to write out your password in your script (it really bothered me prior to writing yagmail!)

For the package/installation, tips and tricks please look at git or pip, available for both Python 2 and 3.

Answered by: First Name760 | Posted: 02-11-2021



Answer 11

you can do like that

import smtplib
from email.mime.text import MIMEText
from email.header import Header


server = smtplib.SMTP('mail.servername.com', 25)
server.ehlo()
server.starttls()

server.login('username', 'password')
from = 'me@servername.com'
to = 'mygfriend@servername.com'
body = 'That A Message For My Girl Friend For tell Him If We will go to eat Something This Nigth'
subject = 'Invite to A Diner'
msg = MIMEText(body,'plain','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = Header(from, 'utf-8')
msg['To'] = Header(to, 'utf-8')
message = msg.as_string()
server.sendmail(from, to, message)

Answered by: Edgar557 | Posted: 02-11-2021



Answer 12

Based on this example I made following function:

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

def send_email(host, port, user, pwd, recipients, subject, body, html=None, from_=None):
    """ copied and adapted from
        https://stackoverflow.com/questions/10147455/how-to-send-an-email-with-gmail-as-provider-using-python#12424439
    returns None if all ok, but if problem then returns exception object
    """

    PORT_LIST = (25, 587, 465)

    FROM = from_ if from_ else user 
    TO = recipients if isinstance(recipients, (list, tuple)) else [recipients]
    SUBJECT = subject
    TEXT = body.encode("utf8") if isinstance(body, unicode) else body
    HTML = html.encode("utf8") if isinstance(html, unicode) else html

    if not html:
        # Prepare actual message
        message = """From: %s\nTo: %s\nSubject: %s\n\n%s
        """ % (FROM, ", ".join(TO), SUBJECT, TEXT)
    else:
                # https://stackoverflow.com/questions/882712/sending-html-email-using-python#882770
        msg = MIMEMultipart('alternative')
        msg['Subject'] = SUBJECT
        msg['From'] = FROM
        msg['To'] = ", ".join(TO)

        # Record the MIME types of both parts - text/plain and text/html.
        # utf-8 -> https://stackoverflow.com/questions/5910104/python-how-to-send-utf-8-e-mail#5910530
        part1 = MIMEText(TEXT, 'plain', "utf-8")
        part2 = MIMEText(HTML, 'html', "utf-8")

        # Attach parts into message container.
        # According to RFC 2046, the last part of a multipart message, in this case
        # the HTML message, is best and preferred.
        msg.attach(part1)
        msg.attach(part2)

        message = msg.as_string()


    try:
        if port not in PORT_LIST: 
            raise Exception("Port %s not one of %s" % (port, PORT_LIST))

        if port in (465,):
            server = smtplib.SMTP_SSL(host, port)
        else:
            server = smtplib.SMTP(host, port)

        # optional
        server.ehlo()

        if port in (587,): 
            server.starttls()

        server.login(user, pwd)
        server.sendmail(FROM, TO, message)
        server.close()
        # logger.info("SENT_EMAIL to %s: %s" % (recipients, subject))
    except Exception, ex:
        return ex

    return None

if you pass only body then plain text mail will be sent, but if you pass html argument along with body argument, html email will be sent (with fallback to text content for email clients that don't support html/mime types).

Example usage:

ex = send_email(
      host        = 'smtp.gmail.com'
   #, port        = 465 # OK
    , port        = 587  #OK
    , user        = "xxx@gmail.com"
    , pwd         = "xxx"
    , from_       = 'xxx@gmail.com'
    , recipients  = ['yyy@gmail.com']
    , subject     = "Test from python"
    , body        = "Test from python - body"
    )
if ex: 
    print("Mail sending failed: %s" % ex)
else:
    print("OK - mail sent"

Btw. If you want to use gmail as testing or production SMTP server, enable temp or permanent access to less secured apps:

Answered by: Daisy742 | Posted: 02-11-2021



Answer 13

Or

import smtplib
 
from email.message import EmailMessage
from getpass import getpass


password = getpass()

message = EmailMessage()
message.set_content('Message content here')
message['Subject'] = 'Your subject here'
message['From'] = "USERNAME@DOMAIN"
message['To'] = "you@mail.com"

try:
    smtp_server = None
    smtp_server = smtplib.SMTP("YOUR.MAIL.SERVER", 587)
    smtp_server.ehlo()
    smtp_server.starttls()
    smtp_server.ehlo()
    smtp_server.login("USERNAME@DOMAIN", password)
    smtp_server.send_message(message)
except Exception as e:
    print("Error: ", str(e))
finally:
    if smtp_server is not None:
        smtp_server.quit()

If you want to use Port 465 you have to create an SMTP_SSL object.

Answered by: Anna970 | Posted: 02-11-2021



Answer 14

Here's a working example for Python 3.x

#!/usr/bin/env python3

from email.message import EmailMessage
from getpass import getpass
from smtplib import SMTP_SSL
from sys import exit

smtp_server = 'smtp.gmail.com'
username = 'your_email_address@gmail.com'
password = getpass('Enter Gmail password: ')

sender = 'your_email_address@gmail.com'
destination = 'recipient_email_address@gmail.com'
subject = 'Sent from Python 3.x'
content = 'Hello! This was sent to you via Python 3.x!'

# Create a text/plain message
msg = EmailMessage()
msg.set_content(content)

msg['Subject'] = subject
msg['From'] = sender
msg['To'] = destination

try:
    s = SMTP_SSL(smtp_server)
    s.login(username, password)
    try:
        s.send_message(msg)
    finally:
        s.quit()

except Exception as E:
    exit('Mail failed: {}'.format(str(E)))

Answered by: Robert105 | Posted: 02-11-2021



Answer 15

What about Red Mail?

Install it:

pip install redmail

Then just:

from redmail import EmailSender

# Configure the sender
email = EmailSender(
    host="YOUR.MAIL.SERVER", 
    port=26,
    username='me@example.com',
    password='<PASSWORD>'
)

# Send an email:
email.send(
    subject="An example email",
    sender="me@example.com",
    receivers=['you@example.com'],
    text="Hello!",
    html="<h1>Hello!</h1>"
)

It has quite a lot of features:

Links:

Answered by: Blake634 | Posted: 02-11-2021



Similar questions

Sending mail with SSL with Python 2.3

I'm working with Python 2.3 and I need to send e-mails with SSL. According to the docs, SMTP_SSL was added in Python 2.6. Is there a way to use SSL also in Python 2.3 (maybe with a third-party module)?


Sending mail via python

I am using Debian 8 and I would like to be able to only send mail via python without installing a full blown mail server system like postfix or without using gmail. I can only see tutorials to send mails with python with full mail system server or via gmail or other internet mail system. Isn't it possible to just send an email and don't care about receiving any? Thanks.


python - Sending mail from a list with smtp

I am attempting to send email to a list of recipients using Python, but I am being told to connect first. import smtplib try: s = smtplib.SMTP('smtp.xxx.com', 587) s.starttls() s.login('barbaramilleraz@xxx.com', 'xxx') message = ''' ...message text... ''' s.connect() with open('players.txt') as f: email = f.readlines() ...


python - Sending an email from Pylons

I am using Pylons to develop an application and I want my controller actions to send emails to certain addresses. Is there a built in Pylons feature for sending email?


python - Django not sending emails to admins

According to the documentation, if DEBUG is set to False and something is provided under the ADMINS setting, Django will send an email whenever the code raises a 500 status code. I have the email settings filled out properly (as I can use send_mail fine) but whenever I intentionally put up erron...


python - How to save a model without sending a signal?

How can I save a model, such that signals arent sent. (post_save and pre_save)


python - sending the data from form to db in django

I have a form in which I can input text through text boxes. How do I make these data go into the db on clicking submit. this is the code of the form in the template. &lt;form method="post" action="app/save_page"&gt; &lt;p&gt; Title:&lt;input type="text" name="title"/&gt; &lt;/p&gt; &lt;p&gt; Name:&lt;input type="text" name="name"/&gt; &lt;/p&gt; &lt;p&gt; Phone:&lt;input type="text" name="phone"/&g...


python - Sending file over socket

I'm have a problem sending data as a file from one end of a socket to the other. What's happening is that both the server and client are trying to read the file so the file never gets sent. I was wondering how to have the client block until the server's completed reading the file sent from the client. I have this working with raw packets using send and recv, but figured this was a cleaner solution...


python - PHP CURL sending POST to Django app issue

This code in PHP sends a HTTP POST to a Django app using CURL lib. I need that this code sends POST but redirect to the page in the same submit. Like a simple form does. The PHP Code: $c = curl_init(); curl_setopt($c, CURLOPT_FOLLOWLOCATION, true); curl_setopt($c, CURLOPT_URL, "http://www.xxx.com"); curl_setopt($c, CURLOPT_POST, true); curl_setopt($c, CURLOPT_POSTFIELDS, 'Var='.$var); curl_e...


Sending Fax with python?

Ok, we aren't in the mid-1980s any more, but anyway. Are there any fax libraries for python?


python - Sending data to django site

I am trying to build a django service to which numerous clients will send data. Each client will represent an authenticated user, who might be connected to the internet or not, so the client will aggregate the data and send them when a connection is available. The data should also be persisted locally so that they are accessed quickly without hitting the server. The nature of the data is simple. It has to do with ...


python - Modify CRUD Form in web2py before sending to view

I cannot seem to find a way to modify a form that has been created via: from gluon.tools import Crud crud = Crud(globals(), db) form = crud.create(db.table_name) Since I am using foreign keys in my table, the auto-generated form only allows an integer (which represents the foreign primary key), but what I want to be able to do is enter whatever data type the foreign data field requires (r...


Sending email from gmail using Python

I'm trying to teaching myself how to program by building programs/scrips that will be useful to me. I'm trying to retool a script I found online to send an email through gmail using a python script (Source). This example has a portion of code to attach files, which I don't want/need. I have tweaked the code so ...


python - Sending Rich Text Format email using Outlook 2003

I am trying to send a Rich Text Format email message using Outlook 2003. The following code results the RTF HTML source code to be dumped into the mail message body. What should I do in order to fix that, and make Outlook display the formatted data and not the source HTML ? import win32com.client RTFTEMPLATE = """&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"&gt; &lt;HTML&gt; &lt;HEAD&gt; &lt;...


python - Sending an email from Pylons

I am using Pylons to develop an application and I want my controller actions to send emails to certain addresses. Is there a built in Pylons feature for sending email?


python - Sending cookies in a SOAP request using Suds

I'm trying to access a SOAP API using Suds. The SOAP API documentation states that I have to provide three cookies with some login data. How can I accomplish this?


python - Django not sending emails to admins

According to the documentation, if DEBUG is set to False and something is provided under the ADMINS setting, Django will send an email whenever the code raises a 500 status code. I have the email settings filled out properly (as I can use send_mail fine) but whenever I intentionally put up erron...


python - How to save a model without sending a signal?

How can I save a model, such that signals arent sent. (post_save and pre_save)


python - Django sending e-mail u'' around headers

I wrote a simple contact form for a client in Django. However, whenever it sends e-mail, it wraps the header values in u'' objects. For example, the From: header is From: (u'my@email.com',) Here's the code that sends the message: The form: class ContactForm(forms.Form): name = forms.CharField(max_length=100) sender = forms.EmailField() subject = forms.CharFiel...


python - Sending custom PyQt signals?

I'm practicing PyQt and (Q)threads by making a simple Twitter client. I have two Qthreads. Main/GUI thread. Twitter fetch thread - fetches data from Twitter every X minutes. So, every X minutes my Twitter thread downloads a new set of status updates (a Python list). I want to hand this list over to the Main/GUI thread, so that it can update the window with these statuses....


python - sending the data from form to db in django

I have a form in which I can input text through text boxes. How do I make these data go into the db on clicking submit. this is the code of the form in the template. &lt;form method="post" action="app/save_page"&gt; &lt;p&gt; Title:&lt;input type="text" name="title"/&gt; &lt;/p&gt; &lt;p&gt; Name:&lt;input type="text" name="name"/&gt; &lt;/p&gt; &lt;p&gt; Phone:&lt;input type="text" name="phone"/&g...


python - Sending file over socket

I'm have a problem sending data as a file from one end of a socket to the other. What's happening is that both the server and client are trying to read the file so the file never gets sent. I was wondering how to have the client block until the server's completed reading the file sent from the client. I have this working with raw packets using send and recv, but figured this was a cleaner solution...


python - PHP CURL sending POST to Django app issue

This code in PHP sends a HTTP POST to a Django app using CURL lib. I need that this code sends POST but redirect to the page in the same submit. Like a simple form does. The PHP Code: $c = curl_init(); curl_setopt($c, CURLOPT_FOLLOWLOCATION, true); curl_setopt($c, CURLOPT_URL, "http://www.xxx.com"); curl_setopt($c, CURLOPT_POST, true); curl_setopt($c, CURLOPT_POSTFIELDS, 'Var='.$var); curl_e...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top