2015-05-30 30 views
2

我寫了一個GAE應用程序,它使用gdata-python-client庫從谷歌電子表格中提取一些信息。直到最近(在上週)谷歌最終刪除了ClientLogin方法之前,一切都一直很好。他們現在只允許oauth2進行身份驗證。這已經完全破壞了我的應用程序,而且我有一段時間讓oauth2工作。使用oauth2返回空數據的Python gdata API

我進入了應用程序的管理控制檯,在憑證管理器中創建了一個服務賬號,並下載了json數據配置。然後我實現了這樣的認證:

path = os.path.join(os.path.split(__file__)[0],'api-auth.json') 
    auth_data = json.load(open(path)) 

    path = os.path.join(os.path.split(__file__)[0],'key.txt') 
    private_key = open(path).read() 

    credentials = SignedJwtAssertionCredentials(
     auth_data['client_email'], 
     private_key, 
     scope=(
     "https://www.googleapis.com/auth/drive", 
     "https://spreadsheets.google.com/feeds", 
     "https://docs.google.com/feeds" 
    ), 
     sub = '<app admin email>') 
    http = httplib2.Http() 
    http = credentials.authorize(http) 
    auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials) 

    gd_client = gdata.spreadsheets.client.SpreadsheetsClient() 
    gd_client = auth2token.authorize(gd_client) 

    # Open the main roster feed 
    roster_sheet_key = '<key from spreadsheet url>' 
    feed = gd_client.GetWorksheets(roster_sheet_key) 

api-auth.json包含從Google下載的json數據的一些字段。 key.txt包含下載數據的私鑰,\ n文本由實際換行符替換。

據我所知,登錄時沒有任何故障。我遇到的問題是它調用GetWorksheets()時。這調用拋出一個解析錯誤:

File "/Users/tim/Desktop/projects/testing/rostermgmt.py", line 184, in get 
    feed = gd_client.GetWorksheets(roster_sheet_key) 
    File "/Users/tim/Desktop/projects/testing/gdata/spreadsheets/client.py", line 108, in get_worksheets 
    **kwargs) 
    File "/Users/tim/Desktop/projects/testing/gdata/client.py", line 640, in get_feed 
    **kwargs) 
    File "/Users/tim/Desktop/projects/testing/gdata/client.py", line 278, in request 
    version=get_xml_version(self.api_version)) 
    File "/Users/tim/Desktop/projects/testing/atom/core.py", line 520, in parse 
    tree = ElementTree.fromstring(xml_string) 
    File "<string>", line 125, in XML 
    ParseError: no element found: line 1, column 0 

我挖到了GDATA庫中的代碼了一下,似乎對數據的HTTP請求返回一個空字符串。我也深入研究了oauth2client庫,它似乎沒有正確地爲oauth標記發起http請求。這裏的一個問題是,看起來有幾種不同的方式可以做到這一點,而Google沒有一個很好的例子作爲「官方」方法。我原來的實施是基於Using OAuth2 with service account on gdata in python,但它顯然不適合我。

回答

3

我整理了一下。有幾件事我不得不採取不同的做法:

  1. 從Google下載私鑰作爲p12文件。使用以下命令將我從Google下載的.p12文件轉換爲pem文件。默認密碼是'notasecret'。

    openssl pkcs12 -in key.p12 -nodes -nocerts > privatekey.pem 
    
  2. 強制使用Google apiclient庫進行身份驗證。最終的代碼如下。 client_email是在GAE控制檯中爲服務用戶提供的電子郵件地址。

    import httplib2 
    from oauth2client.client import SignedJwtAssertionCredentials 
    from apiclient.discovery import build 
    import gdata.spreadsheets 
    import gdata.spreadsheets.client 
    import gdata.gauth 
    import os 
    
    path = os.path.join(os.path.split(__file__)[0],'privatekey.pem') 
    with open(path) as keyfile: 
        private_key = keyfile.read() 
    
    credentials = SignedJwtAssertionCredentials(
        '<client email>', 
        private_key, 
        scope=(
        'https://www.googleapis.com/auth/drive', 
        'https://spreadsheets.google.com/feeds', 
        'https://docs.google.com/feeds', 
    )) 
    http_auth = credentials.authorize(httplib2.Http()) 
    authclient = build('oauth2','v2',http=http_auth) 
    
    auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials) 
    
    gd_client = gdata.spreadsheets.client.SpreadsheetsClient() 
    gd_client = auth2token.authorize(gd_client) 
    
    # Open the main roster feed 
    roster_sheet_key = '<key from spreadsheet url>' 
    feed = gd_client.GetWorksheets(roster_sheet_key) 
    

可惜我無法弄清楚如何使用我一直在使用以前SpreadsheetService API,但SpreadsheetsClient作品不夠好。我沒有注意到兩者之間有什麼顯着的性能差異,因爲我正在使用它。

+0

這給了我一個錯誤: 'oauth2client.client.AccessTokenRefreshError:invalid_grant' 任何幫助嗎? – kadamb

+0

不知道爲什麼它會這樣做。當它調用'authorize'時拋出它?我只是測試了我的設置,它仍然在這裏工作。 – timwoj