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

Introduction

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: https://developers.google.com/gmail/api/quickstart/python

...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 gmailTest.py:

gmailTest.py

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 SCOPES = 'https://www.googleapis.com/auth/gmail.compose' CLIENT_SECRET_FILE = 'gmail_test_secret.json' APPLICATION_NAME = 'Gmail API Python Test' try : import argparse flags = argparse . ArgumentParser ( parents = [ tools . argparser ]) . parse_args () except ImportError : flags = None def SendMessage ( service , user_id , message ): # Send an email message. try : message = ( service . users () . messages () . send ( userId = user_id , body = message ) . execute ()) 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 ): os . makedirs ( credential_dir ) credential_path = os . path . join ( credential_dir , 'gmail-python-test.json' ) 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 = tools . run ( flow , 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 = discovery . build ( 'gmail' , 'v1' , http = http ) testMessage = create_message ( sender , recepient , subject , text_body ) SendMessage ( service , sender , testMessage ) if __name__ == '__main__' : main ( 'username@gmail.com' , 'username@mycompany.com' , 'Test mail subject' , 'Test mail body' )

Credential verification and run

Run it with the flag:

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

The program will stop with a message like this:

Go to the following link in your browser:

https://...

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 "username@mycompany.com" inbox and your "username@gmail.com" 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.