How to send mail with office 365 mail in python?


I'm trying to make a django app that can send mail using an office 365 account.

Is there a simple way to do it?

Appreciate any help!
Errang GenevreAsked:
Who is Participating?
Sending through Office 365 is pretty much the same as sending through anywhere else-- just need to use TLS , port 587 and authentication.

Here's a routine pulled from some of my code to do a send.  It works for me with Office 365.  It might need some changes for python3.
import smtplib, os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import ConfigParser

def send_mail(send_from, send_to, subject, text, files=None, 
                          data_attachments=None, server="", port=587, 
                          tls=True, html=False, images=None,
                          username=None, password=None, 
                          config_file=None, config=None):

    if files is None:
        files = []

    if images is None:
        images = []

    if data_attachments is None:
        data_attachments = []

    if config_file is not None:
        config = ConfigParser.ConfigParser()

    if config is not None:
        server = config.get('smtp', 'server')
        port = config.get('smtp', 'port')
        tls = config.get('smtp', 'tls').lower() in ('true', 'yes', 'y')
        username = config.get('smtp', 'username')
        password = config.get('smtp', 'password')

    msg = MIMEMultipart('related')
    msg['From'] = send_from
    msg['To'] = send_to if isinstance(send_to, basestring) else COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text, 'html' if html else 'plain') )

    for f in files:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( open(f,"rb").read() )
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))

    for f in data_attachments:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( f['data'] )
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % f['filename'])

    for (n, i) in enumerate(images):
        fp = open(i, 'rb')
        msgImage = MIMEImage(
        msgImage.add_header('Content-ID', '<image{0}>'.format(str(n+1)))

    smtp = smtplib.SMTP(server, int(port))
    if tls:

    if username is not None:
        smtp.login(username, password)
    smtp.sendmail(send_from, send_to, msg.as_string())

Open in new window

Using it:
from sendmail import send_mail

send_mail('', '', 'Subject', 'Message Body', 
                   username='', password='my365password')

Open in new window

Errang GenevreAuthor Commented:
Sweet, thanks; I was trying to find what the backend server was, for some reason I wasn't able to see the "". I found it on the account once I knew what I was looking for.

But I'm getting this error now: 550, '5.7.60 SMTP; Client does not have permissions to send as this sender'

I looked online and it says that we need to get the public IP address of the server I'm using; but when I looked at the OpenShift SSH server; I only saw these IP addresses configured in the environment variables:

If they're following the same conventions as the rest of the world.. 127.x.x.x would be a local IP address, right?

Is there any way to fix this error by adding the dns name somewhere on the account? Or does an admin have to do it, I've been given this account by the IT manager.
The error would seem to indicate that the user you're authenticating as doesn't have the email address that you're trying to send as.  Are you trying to send from a different email address than what you're authenticating with?
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

Errang GenevreAuthor Commented:
Yes, initially my code was working with Gmail accounts; with this function call:
send_mail(subject, message, '', [user_email], False)

Open in new window

But I looked at your code and changed it to (the username and password fields were giving me errors, so I looked at ; should I be using another send_mail function?):
send_mail('', '', subject, message,
              auth_user= '', auth_password='password')

Open in new window

I get a success message; but the email doesn't show up in the "Sent" folder on the microsoft account, and it doesn't show up in the email address  it was supposed to send to; is it just slow? Or am I getting a false success message?
Errang GenevreAuthor Commented:
Sorry, just realized you had a send_mail function (been looking at this stuff for way too long...); I tried your method too; I got a few errors with the imports, so I removed them and the corresponding code in your function and I got the same result.

It succeeds, but I don't get an email.
Sorry.  Without any kind of error, pretty tough to troubleshoot.  But I would highly doubt that Microsoft's SMTP service would give you a false success message.  

You can turn on debugging in the smtplib by calling set_debuglevel on the SMTP object.  In the code that I posted that would be done by inserting a:


In line 66.  It will dump the SMTP traffic to stderr.

I don't use django enough to tell you where to look or enable it there.   But personally, I would verify that you can get sending email through Office 365 via python working outside of django first.
Errang GenevreAuthor Commented:
Fantastic! It works... I've placed a bit too much trust in IntelliJ; its showing errors, but it compiles properly.

If its not too much trouble, I'm trying to become a better programmer; I was searching online, and found does it seem like it is worth it? Or are there better alternatives?

Appreciate any feedback!
There's really no substitute for just getting in there and working with the language and from the questions I've seen from you looks to me like you have a fairly good grasp of things.   Sixty bucks isn't a huge investment but at a glance I'm guessing you won't find much in there that will challenge you.  

Another EE user was using  It's free and from the little bit I looked, it looked a fairly good site for basic stuff.  Again I don't know that it will give you much of a challenge.   It was for general python and not targeted specifically at django which I'm guessing might be more what you're after but for free it's probably worth a look.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.