python-3.x - 通过 API 访问受组织限制的 Google 表格
问题描述
我正在编写一个需要从 Google 电子表格读取数据的 Python 3.7 脚本。
有问题的电子表格属于我的工作 Google 帐户所属的组织:我们将其称为“组织”。电子表格权限设置为“组织中知道链接的任何人都可以查看”。这个细节一直阻止我的应用程序工作。
在使用我在组织中的帐户进行身份验证时,我访问了https://console.cloud.google.com/apis/credentials上的凭据仪表板,并创建了一个服务帐户密钥。允许域范围委派,根据使用新的 Google API 控制台项目获取未授权客户端,客户端未经授权使用此方法检索访问令牌。我将 JSON 密钥文件下载到/path/to/service_account_key.json
.
下面我记录了我对gspread
客户端库的尝试 - https://github.com/burnash/gspreadgoogle-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>
我的粗略猜测是,我创建的服务帐户并没有从我那里继承组织中的成员身份。但是,我没有找到确保这一点的选择。我什至要求域管理员从他的管理员帐户中为我创建服务帐户(也启用了域范围委派):没有。
在Google 服务帐户和工作表权限中已经说过,我必须明确地与服务帐户的电子邮件地址共享工作表。当我这样做时,它起作用了,但我也收到一条警告消息,声称该帐户不在组织的 G Suite 域中(再次,它怎么可能不呢?)。
非常感谢
解决方案
尝试将该帐户委派给您组织的特定用户。
它是
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) 或动态传递工作表的所有者电子邮件。
推荐阅读
- javascript - 如何在jstree中单独搜索第n个孩子
- android - 如何在 Android 应用程序中包含不同的语言
- excel - 时间自动刷新
- wordpress - 在媒体 wp api 中上传图片
- c - 我打印学生详细信息的 c 程序不起作用
- python - 在 Django 的详细视图中获取方法
- sql - 如果我对另一个表执行 INNER JOIN,为什么一个表的 SUM 会上升?
- fortran - 在 Fortran 中生成随机数
- php - PhpStorm 无法与 Xdebug 3 一起使用:已配置但 PhpStorm 未检测到 Xdebug
- jakarta-ee - 针对 Micro 和嵌入式运行时的 javax.ejb.TransactionRolledbackLocalException