Using OAuth2 with a service account in gdata in python

I want to use data.photos.service.PhotosService to pop photos from Picasa. I got the service key file XXXXXXXX-privatekey.p12 from the Google console, and now I'm trying to authenticate using the specified key using google.

The documentation for OAUTH2 using appengine led me to think that using the following would be useful:

 f = file(settings.SITE_ROOT + '/aurora/' + settings.PRIVATE_KEY, 'rb') key = f.read() f.close() credentials = SignedJwtAssertionCredentials(settings.SERVICE_ACCOUNT_NAME, key, scope = 'http://picasaweb.google.com/data https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile') http = httplib2.Http() http = credentials.authorize(http) service = build("oauth2", "v2", http=http) user_info = None try: user_info = service.userinfo().get().execute() # neither of these two methods work #gd_client.SetOAuthInputParameters(signature_method = gdata.auth.OAuthSignatureMethod.RSA_SHA1, consumer_key = "asdfasdfasdf.apps.googleusercontent.com", rsa_key = key, two_legged_oauth = True, requestor_id = user_info.get('email')) #gd_client.auth_token = gdata.gauth.TwoLeggedOAuthRsaToken(consumer_key = user_info.get('email'), rsa_private_key = key, requestor_id = user_info.get('email')) except errors.HttpError, e: logging.error('An error occurred: %s', e) user_inf0 = {u'verified_email': True, u'id': u'1234', u'name': u'asdfasdfasdf@developer.gserviceaccount.com', u'email': u'asdfasdfasdf@developer.gserviceaccount.com'} 

The problem is that either method 1 returns an invalid token using SetOAuthInputParameters , or method 2 returns 403 restricted .

I am at the end of my mind, looking through the mountains of code that everyone makes regular with 3 legs, when I really and really don't want to do this. Any ideas / articles I haven't seen yet?

+8
google-app-engine picasa gdata google-api-client
source share
2 answers

Use gdata.gauth.OAuth2TokenFromCredentials.

 auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials) gd_client = auth2token.authorize(gd_client) 

OAuth2TokenFromCredentials is for using apiclient and gdata at the same time. Under the covers, he uses credentials to make sure he has the information needed to make gdata calls.

Please note that if you are still getting 403, it might be something else. I used a service account to access user data and got 403 because I didn’t use the user correctly in the SignedJwtAssertionCredentials call.

UPDATE: the base template is used here:

 from oauth2client.client import SignedJwtAssertionCredentials credentials = SignedJwtAssertionCredentials(    "XXXXXXXXXXX@developer.gserviceaccount.com",    open("keyfile").read(),    scope=(    "https://www.googleapis.com/auth/drive",    "https://spreadsheets.google.com/feeds",    "https://docs.google.com/feeds" ), # For example.    sub="user@gmail.com" ) http = httplib2.Http() http = credentials.authorize(http) # Not needed? See comment below. auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials) gd_client = gdata.photos.service.PhotosService() # For example. gd_client = auth2token.authorize(gd_client) 
+19
source share

If you use MFA on your google account, you need to use the authentication method on the consent screen. It doesn’t work with the Picassa API as it is, since the request API is slightly different.

 import gdata.gauth import os import pickle import gdata.photos.service clientid='xxx' # https://console.developers.google.com/apis/credentials clientsecret='xxx' Scope='https://picasaweb.google.com/data/' User_agent='myself' def GetAuthToken(): if os.path.exists(".token"): with open(".token") as f: token = pickle.load(f) else: token = gdata.gauth.OAuth2Token(client_id=clientid,client_secret=clientsecret,scope=Scope,user_agent=User_agent) print token.generate_authorize_url(redirect_uri='urn:ietf:wg:oauth:2.0:oob') code = raw_input('What is the verification code? ').strip() token.get_access_token(code) with open(".token", 'w') as f: pickle.dump(token, f) return token token = GetAuthToken() gd_client = gdata.photos.service.PhotosService() old_request = gd_client.request def request(operation, url, data=None, headers=None): headers = headers or {} headers['Authorization'] = 'Bearer ' + token.access_token return old_request(operation, url, data=data, headers=headers) gd_client.request = request photos = gd_client.GetUserFeed(kind='photo', limit='10') for photo in photos.entry: print 'Recently added photo title:', photo.title.text 
0
source share

All Articles