通过API访问受组织限制的Google表格

时间:2018-10-17 11:36:54

标签: python-3.x google-sheets google-oauth service-accounts gspread

我正在编写一个Python 3.7脚本,该脚本需要从Google Spreadsheet中读取数据。

有问题的电子表格属于我的工作Google帐户所属的组织:让我们将其称为“组织”。电子表格权限设置为“任何具有链接的组织成员都可以查看”。此细节已阻止我的应用程序正常工作。

我在https://console.cloud.google.com/apis/credentials的凭据仪表板中通过我在Organization中的帐户进行身份验证后,创建了一个服务帐户密钥。根据{{​​3}},允许进行域范围委派。我将JSON密钥文件下载到/path/to/service_account_key.json

下面,我用gspread客户端库-Using New Google API Console project getting unauthorized_client ,Client is unauthorized to retrieve access tokens using this method记录了我的尝试,但是使用google-api-python-client 1.7.4却遇到了完全相同的问题:

import gspread
from oauth2client.service_account import ServiceAccountCredentials

scopes = ['https://www.googleapis.com/auth/spreadsheets.readonly']
credentials = ServiceAccountCredentials.from_json_keyfile_name('/path/to/service_account_key.json', scopes)
gc = gspread.authorize(credentials)
# spreadhseet ID below obfuscated, it's actually the one you get from its URL
sheet = gc.open_by_key('12345-abcdef')

gspread的响应具有与普通Google API v4相同的HTTP代码和消息:

gspread.exceptions.APIError: {
  "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED"
  }
}

但是,如果我将电子表格上的权限(不允许在实际的电子表格上进行更改)更改为“任何具有链接的人都可以查看”,从而删除了“组织”,所有有效!

<Spreadsheet 'Your spreadsheet' id:12345-abcdef>

我的粗略猜测是,我创建的服务帐户未从我那里继承组织的成员身份。但是,我没有选择确保这一点。我什至要求域管理员从他的管理员帐户(也启用了域范围委派)为我创建服务帐户:什么也没有。

https://github.com/burnash/gspread上,我必须与服务帐户的电子邮件地址明确共享工作表。当我这样做时,它起作用了,但是我还收到一条警告消息,声称该帐户不在Organization的G Suite域中(同样,怎么可能不呢?)。

非常感谢

1 个答案:

答案 0 :(得分:1)

尝试将该帐户委派给您组织的特定用户。

就这样

from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http

scope = [
            'https://www.googleapis.com/auth/drive',
            'https://www.googleapis.com/auth/spreadsheets.readonly',
            'https://www.googleapis.com/auth/spreadsheets'
        ]

creds = ServiceAccountCredentials.from_json_keyfile_dict('/path_to_service_account_json_key', scope)

delegated = creds.create_delegated('anyuser@org_domain.com')
delegated_http = delegated.authorize(Http())
spreadsheetservice = gspread.authorize(delegated)

这将使服务帐户委派为用户。 现在,您可以将表格直接分享给上述用户(anyuser@org_domain.com),也可以动态地传递表格所有者的电子邮件。