我正在编写一个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域中(同样,怎么可能不呢?)。
非常感谢
答案 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),也可以动态地传递表格所有者的电子邮件。