Sending e-mails using gmail API

A simple python 3 program that is using gmail API for sending e-mails.

By Kostas Koutsogiannopoulos


This article is a part of a future post regarding asyncronous tasks runing inside a django web application.

We decided to publish it separately because our research for sending e-mail using google's API, led us only to python 2 snippets that doesn't work with python 3.

You can find google's guide for gmail API call with python here:

...and for sending mail sample python code here:

In this article we will accomplish the same result using python 3.

Starting with the basics

Create a new python 3 virtual environment:

username@hostname:~$ virtualenv gmailApp -p python3
Running virtualenv with interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /home/username/gmailApp/bin/python3
Also creating executable in /home/username/gmailApp/bin/python
Installing setuptools, pip, wheel...done.

Activate the environment and check python version:

username@hostname:~$ source gmailApp/bin/activate
(gmailApp) username@hostname:~$ python --version
Python 3.4.3

Install the Google Client Library with all the dependencies:

(gmailApp) username@hostname:~$ pip install --upgrade google-api-python-client

As the message announces, the packages are installed:

Successfully installed google-api-python-client-1.5.1 httplib2-0.9.2 oauth2client-2.2.0 pyasn1-0.1.9 pyasn1-modules-0.0.8 rsa-3.4.2 simplejson-3.8.2 six-1.10.0 uritemplate-0.6

Create a project on Google

Follow this link with a browser:

Click "Continue" to enable API and create project:

Click "Go to credentials":

Select options like the screen above and click "What credentials do I need?":

Give a Product name.

Optionaly click "More customization options" and give more information about your application.

Click Continue:

Click "Download" and save the json file as "gmail_test_secret.json".

Python 3 snippet

In the same directory with the secret json file, create the python program

import httplib2
import os

from apiclient import discovery, errors
import oauth2client
from oauth2client import client
from oauth2client import tools

import base64
from email.mime.text import MIMEText

CLIENT_SECRET_FILE = 'gmail_test_secret.json'
APPLICATION_NAME = 'Gmail API Python Test'

    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

def SendMessage(service, user_id, message): # Send an email message.
      message = (service.users().messages().send(userId=user_id, body=message)
      print ('Message Id: %s' % message['id'])
      return message
    except errors.HttpError as error:
      print ('An error occurred: %s' % error)

def get_credentials(): # Gets valid user credentials from disk.
    credential_dir = '/home/username/gmailApp'
    if not os.path.exists(credential_dir):
    credential_path = os.path.join(credential_dir,

    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials =, store)
        print('Storing credentials to ' + credential_path)
    return credentials

def create_message(sender, to, subject, message_text): # Create a message for an email.
    message = MIMEText(message_text)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    raw = base64.urlsafe_b64encode(bytes(str(message), "utf-8"))
    return {'raw': raw.decode()}

def main( sender, recepient, subject, text_body ):
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service ='gmail', 'v1', http=http)
    testMessage = create_message( sender, recepient, subject, text_body )
    SendMessage( service, sender, testMessage )

if __name__ == '__main__':
    main( '', '', 'Test mail subject', 'Test mail body' )


Credential verification and run

Run it with the flag:

(gmailApp) username@hostname:~$ python --noauth_local_webserver

The program will stop with a message like this:

Go to the following link in your browser:


Enter verification code: 

Now open a browser and paste the link returned by the program:

Click Allow to give access to gmail api from your application:

Grub the code and enter it to your program.

Now the program will print:

Authentication successful.
Storing credentials to /home/username/gmailApp/gmail-python-test.json
Message Id: 155cd723ef9d79f2

Check your "" inbox and your "" outbox for the test message.

The credential verification will not be required again as well as "gmail-python-test.json" file exists in "/home/username/gmailApp" directory.


View epilis's profile on LinkedIn Visit us on facebook X epilis rss feed: Latest articles