Question

Okay, what I'm trying to do is use Google's provisioning API to add members to a google group in the background as they enroll/register inside of google course builder (powered by google app engine).

The first method I tried was using the clientLogin method shown here: https://developers.google.com/google-apps/provisioning/#adding_a_member_to_a_group

groupClient = gdata.apps.groups.client.GroupsProvisioningClient(domain=domain)
groupClient.ClientLogin(email=email, password=password, source='apps')
groupClient.AddMemberToGroup(group_id, member_id)

Although this worked outside of App Engine, after implementing it I ran into some errors and was informed (http://stackoverflow.com/questions/13867535/python-import-gdata-google-apps-engine-course-builder) that using it in App Engine was a bad idea because it was deprecated.

I'm now trying to accomplish this using the python provisioning oAuth example found here (https://developers.google.com/google-apps/help/libraries-samples#provisioningv2)

Here is the source:

"""Sample for the Provisioning API and the Email Settings API with OAuth 2.0."""

__author__ = 'Shraddha Gupta <shraddhag@google.com>'

from optparse import OptionParser
import gdata.apps
import gdata.apps.emailsettings.client
import gdata.apps.groups.client
import gdata.client
import gdata.gauth
import httplib


API_VERSION = '2.0'
BASE_URL = '/a/feeds/group/%s' % API_VERSION
SCOPE = ('https://apps-apis.google.com/a/feeds/groups/')
HOST = 'apps-apis.google.com'


class OAuth2ClientSample(object):
"""OAuth2ClientSample object demos the use of OAuth2Token for retrieving
Members of a Group and updating Email Settings for them."""

def __init__(self, domain, client_id, client_secret):
"""
Args:
  domain: string Domain name (e.g. domain.com)
  client_id: string Client_id of domain admin account.
  client_secret: string Client_secret of domain admin account.
"""
try:
  self.token = gdata.gauth.OAuth2Token(client_id=client_id,
                                       client_secret=client_secret,
                                       scope=SCOPE,
                                       user_agent='oauth2-provisioningv2')
  self.uri = self.token.generate_authorize_url()
  #print 'Please visit this URL to authorize the application:'
  #print self.uri
  # Get the verification code from the standard input.
  #code = raw_input('What is the verification code? ').strip()
  conn = httplib.HTTPConnection(self.uri)
  conn.request("GET")
  r1 = conn.getresponse()
  print r1.read()
  self.token.get_access_token(code)
  except gdata.gauth.OAuth2AccessTokenError, e:
  print 'Invalid Access token, Check your credentials %s' % e
  exit(0)
  self.domain = domain
  self.baseuri = '%s/%s' % (BASE_URL, domain)
  self.client = gdata.apps.groups.client.GroupsProvisioningClient(
    domain=self.domain, auth_token=self.token)
# Authorize the client. 
# This will add the Authorization header to all future requests.
self.token.authorize(self.client)
self.email_client = gdata.apps.emailsettings.client.EmailSettingsClient(
    domain=self.domain, auth_token=self.token)
self.token.authorize(self.email_client)

def create_filter(self, feed):
"""Creates a mail filter that marks as read all messages not containing
Domain name as one of their words for each member of the group.

Args:
  feed: GroupMemberFeed members whose emailsettings need to updated
"""
for entry in feed.entry:
  user_name, domain = entry.member_id.split('@', 1)
  if entry.member_type == 'User' and domain == self.domain:
    print 'creating filter for %s' % entry.member_id
    self.email_client.CreateFilter(user_name,
                                   does_not_have_the_word=self.domain,
                                   mark_as_read=True)
  elif entry.member_type == 'User':
    print 'User belongs to other Domain %s' %entry.member_id
  else:
    print 'Member is a group %s' %entry.member_id

def run(self, group):
feed = self.client.RetrieveAllMembers(group)
self.create_filter(feed)


def main():

  sample = OAuth2ClientSample('mydomain.mygbiz.com',
  'mydomain', 'My client secret')
  sample.run('test')


if __name__ == '__main__':
  main()

I realize that this is just going to list the members of my group, but right now I'm just trying to get past the authentication stage.

The code I'm having referring to specifically is:

  #print 'Please visit this URL to authorize the application:'
  #print self.uri
  # Get the verification code from the standard input.
  #code = raw_input('What is the verification code? ').strip()
  conn = httplib.HTTPConnection(self.uri)
  conn.request("GET")
  r1 = conn.getresponse()
  print r1.read()
  self.token.get_access_token(code)

I commented out the original code which takes a raw input for the token. This needs to run seamlessly in the background so I need it to retrieve the token automatically. I had started to httplib, but it returned an error with the URL.

I have a couple of questions.

First, is this the simplest approach for what I need to do, it seems like overkill. clientLogin, was so much more elegant and simple.

Second, if I must do it this way, how exactly do I retrieve the token once I have the validation URL? Do I use httplib?

I'm seriously considering just simulating a browser inside of Python... why is this process so complex?

Any help provided is truly appreciated.

Edit: I just wanted to note, that the reason for doing all of this in the first place is this is for the development of a MOOC in course builder which could have members in the tens to hundreds of thousands. The discussion platform will be google groups, but we cannot have it open to the public, but we also cannot manually approve each member.

Was it helpful?

Solution

You could continue to use ClientLogin, deprecation is slow process (https://developers.google.com/accounts/terms). I use Oauth 2 for my apps, but I don't use app engine. You can download the client_secrets.json file from the APIs Console page for your project (https://code.google.com/apis/console) and retrieve secret etc. from the file. For example:

import oauth2client.client
import oauth2client.file
import oauth2client.tools
...
oauth2_flow = oauth2client.client.flow_from_clientsecrets('client_secrets.json',
  scope='list of scopes',message='Missing client_secrets.json file message')
storage = oauth2client.file.Storage('creedentials.ouath2')
oauth2_credentials = storage.get()
if oauth2_credentials is None or oauth2_credentials.invalid:
  oauth2_credentials = oauth2client.tools.run(oauth2_flow, storage)
...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top