Python smtplib - No recipient after sending mail - python

I recently wrote a script that sent me an email if a website I wanted to monitor had changed using smtplib. The program works, and I get the email but when I look at the sent email (as I am sending myself the email from the same account), it says that there is no recipient or 'To:' address, only a Bcc with the address I want the email to be sent to. Is this a feature of smtplib -- that it doesn't actually add a 'To:' address, only Bcc addresses? code is as follows:
if (old_source != new_source):
# now we create a mesasge to send via email
fromAddr = "example#gmail.com"
toAddr = "example#gmail.com"
msg = ""
# smtp login
username = "example#gmail.com"
pswd = "password"
# create server object and login to the gmail smtp
server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server.login(username, pswd)
server.sendmail(fromAddr, toAddr, msg)
server.quit()

Updating your code as follows will do the trick:
if (old_source != new_source):
# now we create a mesasge to send via email
fromAddr = "example#gmail.com"
toAddr = "example#gmail.com"
msg = ""
# smtp login
username = "example#gmail.com"
pswd = "password"
# create server object and login to the gmail smtp
server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
header = 'To:' + toAddr + '\n' + 'From: ' + fromAddr + '\n' + 'Subject:testing \n'
msg = header + msg
server.login(username, pswd)
server.sendmail(fromAddr, toAddr, msg)
server.quit()

Try manually adding any headers to your message, separated from the body by a blank line e.g.:
...
msg="""From: sender#domain.org
To: recipient#otherdomain.org
Subject: Test mail
Mail body, ..."""
...

Try this, seems to work for me.
#!/usr/bin/python
#from smtplib import SMTP # Standard connection
from smtplib import SMTP_SSL as SMTP #SSL connection
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
sender = 'example#gmail.com'
receivers = ['example#gmail.com']
msg = MIMEMultipart()
msg['From'] = 'example#gmail.com'
msg['To'] = 'example#gmail.com'
msg['Subject'] = 'simple email via python test 1'
message = 'This is the body of the email line 1\nLine 2\nEnd'
msg.attach(MIMEText(message))
ServerConnect = False
try:
smtp_server = SMTP('smtp.gmail.com','465')
smtp_server.login('######gmail.com', '############')
ServerConnect = True
except SMTPHeloError as e:
print "Server did not reply"
except SMTPAuthenticationError as e:
print "Incorrect username/password combination"
except SMTPException as e:
print "Authentication failed"
if ServerConnect == True:
try:
smtp_server.sendmail(sender, receivers, msg.as_string())
print "Successfully sent email"
except SMTPException as e:
print "Error: unable to send email", e
finally:
smtp_server.close()

Just throwing it out there: please try yagmail. Disclaimer: I'm the maintainer, but I feel like it can help everyone out!
It really provides a lot of defaults: I'm quite sure you'll be able to send an email directly with:
import yagmail
yag = yagmail.SMTP(username, password)
yag.send(to_addrs, contents = msg)
Which will also set the headers :)
You'll have to install yagmail first with either:
pip install yagmail # python 2
pip3 install yagmail # python 3
Once you will want to also embed html/images or add attachments, you'll really love the package!
It will also make it a lot safer by preventing you from having to have your password in the code.

Related

send email with Gmail Python

I am attempting to send an email, but I run into this error:
smtplib.SMTPAuthenticationError: (534, b'5.7.9 Application-specific password required. Learn more at\n5.7.9 https://support.google.com/mail/?p=InvalidSecondFactor d2sm13023190qkl.98 - gsmtp')
In the web URL i dont see anything super useful, would anyone have any tips? For SO purposes I left the email account passwords as test versus sharing my person info..
import smtplib
import ssl
# User configuration
sender_email = 'test#gmail.com'
receiver_email = 'test#gmail.com'
password = 'test'
# Email text
email_body = '''
This is a test email sent by Python. Isn't that cool?
'''
# Creating a SMTP session | use 587 with TLS, 465 SSL and 25
server = smtplib.SMTP('smtp.gmail.com', 587)
# Encrypts the email
context = ssl.create_default_context()
server.starttls(context=context)
# We log in into our Google account
server.login(sender_email, password)
# Sending email from sender, to receiver with the email body
server.sendmail(sender_email, receiver_email, email_body)
print('Email sent!')
print('Closing the server...')
server.quit()
I tried my best... I think this should work!
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
email = "test#gmail.com" # the email where you sent the email
password = "yourPassword"
send_to_email = "yourEmail#gmail.com" # for whom
subject = "Gmail"
message = "This is a test email sent by Python. Isn't that cool?!"
msg = MIMEMultipart()
msg["From"] = email
msg["To"] = send_to_email
msg["Subject"] = subject
msg.attach(MIMEText(message, 'plain'))
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(email, password)
text = msg.as_string()
server.sendmail(email, send_to_email, text)
server.quit()
You must allow the "Less secure apps" in Google configurations.
Here is the link of another thread about it : Link

add sender's name in the from field of the email in python

I am trying to send email with below code.
import smtplib
from email.mime.text import MIMEText
sender = 'sender#sender.com'
def mail_me(cont, receiver):
msg = MIMEText(cont, 'html')
recipients = ",".join(receiver)
msg['Subject'] = 'Test-email'
msg['From'] = "XYZ ABC"
msg['To'] = recipients
# Send the message via our own SMTP server.
try:
s = smtplib.SMTP('localhost')
s.sendmail(sender, receiver, msg.as_string())
print "Successfully sent email"
except SMTPException:
print "Error: unable to send email"
finally:
s.quit()
cont = """\
<html>
<head></head>
<body>
<p>Hi!<br>
How are you?<br>
Here is the link you wanted.
</p>
</body>
</html>
"""
mail_me(cont,['xyz#xyzcom'])
I want "XYZ ABC" to appear as the sender's name when the email is received and its email address as 'sender#sender.com'. but when i receive email i am receiving weird details in "from" fields of the email message.
[![from: XYZ#<machine-hostname-appearing-here>
reply-to: XYZ#<machine-hostname-appearing-here>,
ABC#<machine-hostname-appearing-here>][1]][1]
I have attached a screenshot of the email that i receive.
how can i fix this according to my need.
This should work:
msg['From'] = "Your name <Your email>"
Example below:
import smtplib
from email.mime.text import MIMEText
def send_email(to=['example#example.com'],
f_host='example.example.com',
f_port=587,
f_user='example#example.com',
f_passwd='example-pass',
subject='default subject',
message='content message'):
smtpserver = smtplib.SMTP(f_host, f_port)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
smtpserver.login(f_user, f_passwd) # from email credential
msg = MIMEText(message, 'html')
msg['Subject'] = 'My custom Subject'
msg['From'] = "Your name <Your email>"
msg['To'] = ','.join(to)
for t in to:
smtpserver.sendmail(f_user, t, msg.as_string()) # you just need to add
# this in for loop in
# your code.
smtpserver.close()
print('Mail is sent successfully!!')
cont = """
<html>
<head></head>
<body>
<p>Hi!<br>
How are you?<br>
Here is the link you wanted.
</p>
</body>
</html>
"""
try:
send_email(message=cont)
except:
print('Mail could not be sent')
Just tested the following code with gmx.com and it works fine. Although, whether you get the same mileage is a moot point.
I have replaced all references to my email service with gmail
#!/usr/bin/python
#from smtplib import SMTP # Standard connection
from smtplib import SMTP_SSL as SMTP #SSL connection
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
sender = 'example#gmail.com'
receivers = ['example#gmail.com']
msg = MIMEMultipart()
msg['From'] = 'example#gmail.com'
msg['To'] = 'example#gmail.com'
msg['Subject'] = 'simple email via python test 1'
message = 'This is the body of the email line 1\nLine 2\nEnd'
msg.attach(MIMEText(message))
ServerConnect = False
try:
smtp_server = SMTP('smtp.gmail.com','465')
smtp_server.login('#name##gmail.com', '#password#')
ServerConnect = True
except SMTPHeloError as e:
print "Server did not reply"
except SMTPAuthenticationError as e:
print "Incorrect username/password combination"
except SMTPException as e:
print "Authentication failed"
if ServerConnect == True:
try:
smtp_server.sendmail(sender, receivers, msg.as_string())
print "Successfully sent email"
except SMTPException as e:
print "Error: unable to send email", e
finally:
smtp_server.close()
This should fix it:
Replace mail_me(cont,['xyz#xyzcom'])
with
mail_me(cont,'xyz#xyz.com')
The name comes from the FROM header. Refer to this answer please Specify a sender when sending mail with Python (smtplib)
A space is not a valid character in an email address. Special characters are only allowed in the external representation that shall be enclosed in double quotes. Additionaly, most SMTP servers actually use header rewriting to ensure that addresses are in standard format. As yours actually contains a space it is splitted and as it is not enclosed in quotes, the server address is appended to it.
You have just to replace msg['From'] = "XYZ ABC" with
msg['From'] = '"XYZ ABC"'
forcing inclusion of the address in double quotes.
import smtplib
from email.mime.text import MIMEText
def send_email(to=['example#example.com'], f_host='example.example.com', f_port=587, f_user='example#example.com', f_passwd='example-pass', subject='default subject', message='content message'):
smtpserver = smtplib.SMTP(f_host, f_port)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
smtpserver.login(f_user, f_passwd) # from email credential
msg = MIMEText(message, 'html')
msg['Subject'] = 'My custom Subject'
msg['From'] = "Admin"
msg['To'] = ','.join(to)
for t in to:
smtpserver.sendmail(f_user, t, msg.as_string()) # you just need to add this in for loop in your code.
smtpserver.close()
print('Mail is sent successfully!!')
cont = """\
<html>
<head></head>
<body>
<p>Hi!<br>
How are you?<br>
Here is the link you wanted.
</p>
</body>
</html>
"""
try:
send_email(message=cont)
except:
print('Mail could not be sent')
above method I have tried to send mail which is worked for me even I am able to send mail to my gmail account(in spam folder).
Let me know if you face any other related problem.
While the above methods are fine, a more explicit way is to make use of Address from email.headerregistry
The Address class takes 4 parameters:
(quoted from docs)
display_name - The display name portion of the address, if any, with all quoting removed. If the address does not have a display name, this attribute will be an empty string.
username - The username portion of the address, with all quoting removed.
domain - The domain portion of the address.
addr_spec - The username#domain portion of the address, correctly quoted for use as a bare address (the second form shown above). This attribute is not mutable.
import smtplib
from email.message import EmailMessage
from email.headerregistry import Address
msg = EmailMessage()
msg.set_content('Hello Stackoverflow!')
msg['Subject'] = 'SO'
msg['From'] = Address(display_name="Name", addr_spec="info#mydomain.com")
msg['To'] = "receiver#domain.com"
# Send the message via our own SMTP server.
server = smtplib.SMTP_SSL('smpt.gmail.net', 465) # place your own host
server.login("info#mydomain.com", "mypassword")
server.send_message(msg)
server.quit()

Cannot send an email with python smtp

I am developing an application using python where I need to send a file through mail. I wrote a program to send the mail but dont know there's something wrong. The code is posted below. Please any one help me with this smtp library. Is there's anything i m missing? And also can someone please tell me what will be the host in smtp! I am using smtp.gmail.com.
Also can any one tell me how can i email a file (.csv file). Thanks for the help!
#!/usr/bin/python
import smtplib
sender = 'someone#yahoo.com'
receivers = ['someone#yahoo.com']
message = """From: From Person <someone#yahoo.com>
To: To Person <someone#yahoo.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
try:
smtpObj = smtplib.SMTP('smtp.gmail.com')
smtpObj.sendmail(sender, receivers, message)
print "Successfully sent email"
except:
print "Error: unable to send email"
You aren't logging in. There are also a couple reasons you might not make it through including blocking by your ISP, gmail bouncing you if it can't get a reverse DNS on you, etc.
try:
smtpObj = smtplib.SMTP('smtp.gmail.com', 587) # or 465
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login(account, password)
smtpObj.sendmail(sender, receivers, message)
print "Successfully sent email"
except:
print "Error: unable to send email"
I just noticed your request to be able to attach a file. That changes things since now you need to deal with encoding. Still not that tough to follow though I don't think.
import os
import email
import email.encoders
import email.mime.text
import smtplib
# message/email details
my_email = 'myemail#gmail.com'
my_passw = 'asecret!'
recipients = ['jack#gmail.com', 'jill#gmail.com']
subject = 'This is an email'
message = 'This is the body of the email.'
file_name = 'C:\\temp\\test.txt'
# build the message
msg = email.MIMEMultipart.MIMEMultipart()
msg['From'] = my_email
msg['To'] = ', '.join(recipients)
msg['Date'] = email.Utils.formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(email.MIMEText.MIMEText(message))
# build the attachment
att = email.MIMEBase.MIMEBase('application', 'octet-stream')
att.set_payload(open(file_name, 'rb').read())
email.Encoders.encode_base64(att)
att.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file_name))
msg.attach(att)
# send the message
srv = smtplib.SMTP('smtp.gmail.com', 587)
srv.ehlo()
srv.starttls()
srv.login(my_email, my_passw)
srv.sendmail(my_email, recipients, msg.as_string())

Python: "subject" not shown when sending email using smtplib module

I am successfully able to send email using the smtplib module. But when the emial is sent, it does not include the subject in the email sent.
import smtplib
SERVER = <localhost>
FROM = <from-address>
TO = [<to-addres>]
SUBJECT = "Hello!"
message = "Test"
TEXT = "This message was sent with Python's smtplib."
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()
How should I write "server.sendmail" to include the SUBJECT as well in the email sent.
If I use, server.sendmail(FROM, TO, message, SUBJECT), it gives error about "smtplib.SMTPSenderRefused"
Attach it as a header:
message = 'Subject: {}\n\n{}'.format(SUBJECT, TEXT)
and then:
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()
Also consider using standard Python module email - it will help you a lot while composing emails. Using it would look like this:
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = SUBJECT
msg['From'] = FROM
msg['To'] = TO
msg.set_content(TEXT)
server.send_message(msg)
This will work with Gmail and Python 3.6+ using the new "EmailMessage" object:
import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg.set_content('This is my message')
msg['Subject'] = 'Subject'
msg['From'] = "me#gmail.com"
msg['To'] = "you#gmail.com"
# Send the message via our own SMTP server.
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.login("me#gmail.com", "password")
server.send_message(msg)
server.quit()
try this:
import smtplib
from email.mime.multipart import MIMEMultipart
msg = MIMEMultipart()
msg['From'] = 'sender_address'
msg['To'] = 'reciver_address'
msg['Subject'] = 'your_subject'
server = smtplib.SMTP('localhost')
server.sendmail('from_addr','to_addr',msg.as_string())
You should probably modify your code to something like this:
from smtplib import SMTP as smtp
from email.mime.text import MIMEText as text
s = smtp(server)
s.login(<mail-user>, <mail-pass>)
m = text(message)
m['Subject'] = 'Hello!'
m['From'] = <from-address>
m['To'] = <to-address>
s.sendmail(<from-address>, <to-address>, m.as_string())
Obviously, the <> variables need to be actual string values, or valid variables, I just filled them in as place holders. This works for me when sending messages with subjects.
See the note at the bottom of smtplib's documentation:
In general, you will want to use the email package’s features to construct an email message, which you can then convert to a string and send via sendmail(); see email: Examples.
Here's the link to the examples section of email's documentation, which indeed shows the creation of a message with a subject line. https://docs.python.org/3/library/email.examples.html
It appears that smtplib doesn't support subject addition directly and expects the msg to already be formatted with a subject, etc. That's where the email module comes in.
import smtplib
# creates SMTP session
List item
s = smtplib.SMTP('smtp.gmail.com', 587)
# start TLS for security
s.starttls()
# Authentication
s.login("login mail ID", "password")
# message to be sent
SUBJECT = "Subject"
TEXT = "Message body"
message = 'Subject: {}\n\n{}'.format(SUBJECT, TEXT)
# sending the mail
s.sendmail("from", "to", message)
# terminating the session
s.quit()
I think you have to include it in the message:
import smtplib
message = """From: From Person <from#fromdomain.com>
To: To Person <to#todomain.com>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP HTML e-mail test
This is an e-mail message to be sent in HTML format
<b>This is HTML message.</b>
<h1>This is headline.</h1>
"""
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, message)
print "Successfully sent email"
except SMTPException:
print "Error: unable to send email"
code from: http://www.tutorialspoint.com/python/python_sending_email.htm
In case of wrapping it in a function, this should work as a template.
def send_email(login, password, destinations, subject, message):
server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server.login(login, password)
message = 'Subject: {}\n\n{}'.format(subject, message)
for destination in destinations:
print("Sending email to:", destination)
server.sendmail(login, destinations, message)
server.quit()
try this out :
from = "myemail#site.com"
to= "someemail#site.com"
subject = "Hello there!"
body = "Have a good day."
message = "Subject:" + subject + "\n" + body
server.sendmail(from, , message)
server.quit()

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()
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
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
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')
...
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.
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()
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.
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/
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()
You should make sure you format the date in the correct format - RFC2822.
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.
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)
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:
login to google mail/account
go to: https://myaccount.google.com/lesssecureapps
enable
send email using this function or similar
(recommended) go to: https://myaccount.google.com/lesssecureapps
(recommended) disable
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.
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)))
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:
Email attachments from various sources
Embedding images and plots to the HTML body
Templating emails with Jinja
Preconfigured Gmail and Outlook
Logging handler
Flask extension
Links:
Source code
Documentation
Releases
Based on madman2890, updated a few things as well as removed the need for mailserver.quit()
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text 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))
with smtplib.SMTP('smtp-mail.outlook.com',587) as mail_server:
# identify ourselves to smtp gmail client
mail_server.ehlo()
# secure our email with tls encryption
mail_server.starttls()
# re-identify ourselves as an encrypted connection
mail_server.ehlo()
mail_server.login('me#gmail.com', 'mypassword')
mail_server.sendmail('me#gmail.com','you#gmail.com',msg.as_string())

Categories