Accessing the Google APIs using Oauth 2 in Python

In its simplest form, Oauth is as in this document I had created earlier.

Oauth is such a simple protocol and so much of fuss is being made about it, its so simple that you can understand it even by reading its Specification documentation!

Below pic shows the flow

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+



Authentication and Authorisation are two different things, here we will cover authorisation.
Let's take Python 

Now the first thing is to get a consumer key and secret. Which can be go by going and registering on 
on the API Access pane of the Google APIs Console.



Google recommends that we use client libraries as they are safe hence we will be using the oauth2client-module. Which is already there within the Google's Client Library.

Before we go ahead, lets discuss the "flow"

First using the Flow we will get credentials which can access a certain service and that will be stored. 

FLOW ===> Credentials ==> Storage

"Flow" class -- flow_from_clientsecrets 


got by from oauth2client.client import flow_from_clientsecrets
This is used to acquire credentials that authorise our app (to access user's data). In order for a user to grant access, OAuth 2.0 steps require your application to potentially redirect their browser multiple times. Lets see below how the flow object is instantiated using the flow class.

flow = flow_from_clientsecrets('path of client_secrets.json',
                        scope='https://www.googleapis.com/auth/Resource',
                               redirect_uri='http://example.com/auth_return')
you can download a client_secrets.json file from Google API console for your app and place it in the folder where the python script is located.
Scope is telling the script that you want access only a particular resource, like Google Groups and calendar. This is like fool proofing in case you loose control of this script, it could go crazy on all the resources. So we limit it upfront-- Damage control ;)

Though as per the flow, Credentials should have been the next topic, we just have a place holder for the credentials to be defined. 

Storage 

First we import this class by  
from oauth2client.file import Storage
observe that its oauth2client.file and not client
then 

storage = Storage('some file.dat')
this command will create a file by that name, and have the credentials stored into it for further transactions.

Now for the credentials finally, but before we go there, oauth2client.tools.run() from its documentation here is what it says

The run() function is called from your application and runs through all the
steps to obtain credentials. It takes a Flow argument and attempts to open an
authorization server page in the user's default web browser. The server asks
the user to grant your application access to the user's data. If the user
grants access, the run() function returns new credentials. The new credentials
are also stored in the Storage argument, which updates the file associated
with the Storage object.

so to get it into python we do 

from oauth2client.tools import run

Credentials 

The Flow object can create the Credentials for you.  
A Credentials object holds refresh and access tokens that authorize access to a single user's data. 
so finally to create credentials

credentials = run(flow, storage)

So the now the bare minimum code so far is as in the screenshot below, so when we run it, it opens our default browser as below


A file which we had specified earlier called "some file.dat" gets created and holds all authorisation token and etc now, which has the info as below

{"_module": "oauth2client.client", "token_expiry": "2013-11-29T15:13:12Z", "access_token": "y"...}

Now to avoid having to go through the process of going to a browser and authorising this app always, what we can do is check if there are already some credentials in the stored file and if they are there use, them else create a new one. 

if credentials is None or credentials.invalid:
        print 'invalid credentials'
        # Save the credentials in storage to be used in subsequent runs.
        credentials = run(FLOW, storage)


Finally, using these credentials we have got!

These objects are applied to httplib2.Http objects to authorize access. 

We will use the authorise() function of the Credentials class to apply necessary credential headers to all requests made by an httplib2.Http instance:

httpplib2.http is used to place requests to the web, see the below screenshot, where I am just trying to get the unauthenticated page, like Google. 

from httplib2 import Http 
note the caps in Http



so we authorise our request using the "credentials' function:

http = credentials.authorize(http='h')

Once an httplib2.Http object has been authorised, it is typically passed to the build function:


service = build('calendar', 'v3', http=http)

service = build('groupssettings', 'v1', http=http)

Popular posts from this blog

Ansible - Error - stderr: E: There are problems and -y was used without --force-yes

Error: SMTPIN_ADDED_BROKEN@mx.google.com