views:

93

answers:

1

Hi, I'm trying to grab the Gmail atom feed from a python application using OAuth. I have a working application that downloads the Google Reader feed, and I think it should simply be a matter of changing the scope and feed URLs. After replacing the URLs I can still successfully get Request and Access tokens, but when I try to grab the feed using the Access token I get a "401 Unauthorized" error. Here's my simple test program:

import urlparse
import oauth2 as oauth

scope = "https://mail.google.com/mail/feed/atom/"
sub_url = scope + "unread"

request_token_url = "https://www.google.com/accounts/OAuthGetRequestToken?scope=%s&xoauth_displayname=%s" % (scope, "Test Application")
authorize_url = 'https://www.google.com/accounts/OAuthAuthorizeToken'
access_token_url = 'https://www.google.com/accounts/OAuthGetAccessToken'

oauth_key = "anonymous"
oauth_secret = "anonymous"

consumer = oauth.Consumer(oauth_key, oauth_secret)
client = oauth.Client(consumer)

# Get a request token.
resp, content = client.request(request_token_url, "GET")
request_token = dict(urlparse.parse_qsl(content))

print "Request Token:"
print "    - oauth_token        = %s" % request_token['oauth_token']
print "    - oauth_token_secret = %s" % request_token['oauth_token_secret']
print

# Step 2: Link to web page where the user can approve the request token.
print "Go to the following link in your browser:"
print "%s?oauth_token=%s" % (authorize_url, request_token['oauth_token'])
print

raw_input('Press enter after authorizing.')

# Step 3: Get access token using approved request token
token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret'])
client = oauth.Client(consumer, token)

resp, content = client.request(access_token_url, "POST")
access_token = dict(urlparse.parse_qsl(content))

print "Access Token:"
print "    - oauth_token        = %s" % access_token['oauth_token']
print "    - oauth_token_secret = %s" % access_token['oauth_token_secret']
print

# Access content using access token
token = oauth.Token(access_token['oauth_token'], access_token['oauth_token_secret'])
client = oauth.Client(consumer, token)

resp, content = client.request(sub_url, 'GET')
print content

You'll notice that I'm using 'anonymous/anonymous' as my OAuth key/secret, as mentioned in the Google documents for unregistered applications. This works fine for google reader, so I don't see any reason why it shouldn't work for Gmail. Does anyone have any idea on why this might not work, or how I could go about troubleshooting it? Thanks.

+2  A: 

You might want to try accessing Google's IMAP servers with OAuth instead of using the ATOM feed. After a little googling I found this:

"Gmail supports OAuth over IMAP and SMTP via a standard they call XOAUTH. This allows you to authenticate against Gmail's IMAP and SMTP servers using an OAuth token and secret. It also has the added benefit of allowing you to use vanilla SMTP and IMAP libraries. The python-oauth2 package provides both IMAP and SMTP libraries that implement XOAUTH and wrap imaplib.IMAP4_SSL and smtplib.SMTP. This allows you to connect to Gmail with OAuth credentials using standard Python libraries."

from http://github.com/simplegeo/python-oauth2

alecwh
Thanks. This looks like what I need. I'm not sure why the gmail feed isn't working, but afaict it seems to be second-class citizen in the gdata APIs anyway.
No problem! Happy to help.
alecwh