Sheets API:使用 Python 从电子表格中读取数据
Sheets API: reading data from spreadsheet with Python
我正在尝试从共享 我的个人电子邮件地址 的 Google 电子表格中检索数据。我在 json 文件中设置了一个服务帐户,如下所示:
{
"type": "service_account",
"project_id": "my-project-name",
"private_key_id": "012345678901234567890123456789",
"private_key": "-----BEGIN PRIVATE KEY-----\xxxxx\n-----END PRIVATE KEY-----\n",
"client_email": "my-name@my-project-name.iam.gserviceaccount.com",
"client_id": "9876543210",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/my-name%40my-project-name.iam.gserviceaccount.com"
}
我的代码(见下文)的基本原理是这样的:给定一个共享给我的 url 电子表格 (--> spreadsheet_id
、sheet_id
),它找到选项卡名称 (name
),并使用它来检索最终转换为 pd.DataFrame
.
的数据 (data_values
)
现在我的问题是,当我 运行 在公开可用的在线电子表格上使用此功能时,它工作正常,但每当我尝试 运行 在我有权访问的电子表格上使用它时,但它不是公开可用的,它失败并出现以下错误:
Error code: 403, PERMISSION_DENIED: The request is missing a valid API key
好像服务帐户(链接到我的 Google 帐户,因此链接到我的个人电子邮件)无法访问共享到我的个人帐户的内容。这是设计使然吗?我怎样才能克服这个?我非常喜欢自动解决方案,而不是必须分别手动设置每个电子表格的访问权限,以便与我的服务帐户地址共享,而不是我的个人地址。
编辑: 从那时起,我手动将我的服务帐户的电子邮件地址添加到其中一个文件中,并且成功了。看来,服务帐户无法访问我的个人电子邮件文件,只能访问那些特别 与服务帐户共享的文件?我是否也应该始终与我的服务帐户电子邮件地址共享每个文件?
代码:
def get_spreadsheet_data(name, spreadsheet_id, sheet_id, service_account_json_path, scope):
creds = ServiceAccountCredentials.from_json_keyfile_name(service_account_json_path, scope)
service = build('sheets', 'v4', credentials=creds)
sheets = service.spreadsheets()
# If name is not provided, generate it from spreadsheet_id
if not name:
a = sheets.get(
spreadsheetId=spreadsheet_id,
fields='sheets(properties(index,sheetId,title))'
).execute()
name = [sheet['properties']['title'] for sheet in a['sheets'] \
if int(sheet['properties']['sheetId']) == int(sheet_id)][0]
data_table = sheets.values().get(spreadsheetId=spreadsheet_id, range=name).execute()
data_values = data_table.get('values', [])
df = pd.DataFrame(data_values)
return df
出于文档目的发布此内容。
作为,服务帐户和您的普通帐户是完全不同的帐户。
服务帐户本身只能访问与其共享(或由其创建)的文件,而不能访问与您的常规帐户共享的文件。
如官方文档中所述:
Typically, an application uses a service account when the application uses Google APIs to work with its own data rather than a user's data.
如果您有 Workspace 帐户,则可以使用该服务帐户代表您域中的其他用户(例如您的常规帐户):请参阅 Delegating domain-wide authority to the service account 了解相关信息。否则,无法使用您的服务帐户访问用户文件。
参考:
我正在尝试从共享 我的个人电子邮件地址 的 Google 电子表格中检索数据。我在 json 文件中设置了一个服务帐户,如下所示:
{
"type": "service_account",
"project_id": "my-project-name",
"private_key_id": "012345678901234567890123456789",
"private_key": "-----BEGIN PRIVATE KEY-----\xxxxx\n-----END PRIVATE KEY-----\n",
"client_email": "my-name@my-project-name.iam.gserviceaccount.com",
"client_id": "9876543210",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/my-name%40my-project-name.iam.gserviceaccount.com"
}
我的代码(见下文)的基本原理是这样的:给定一个共享给我的 url 电子表格 (--> spreadsheet_id
、sheet_id
),它找到选项卡名称 (name
),并使用它来检索最终转换为 pd.DataFrame
.
data_values
)
现在我的问题是,当我 运行 在公开可用的在线电子表格上使用此功能时,它工作正常,但每当我尝试 运行 在我有权访问的电子表格上使用它时,但它不是公开可用的,它失败并出现以下错误:
Error code: 403, PERMISSION_DENIED: The request is missing a valid API key
好像服务帐户(链接到我的 Google 帐户,因此链接到我的个人电子邮件)无法访问共享到我的个人帐户的内容。这是设计使然吗?我怎样才能克服这个?我非常喜欢自动解决方案,而不是必须分别手动设置每个电子表格的访问权限,以便与我的服务帐户地址共享,而不是我的个人地址。
编辑: 从那时起,我手动将我的服务帐户的电子邮件地址添加到其中一个文件中,并且成功了。看来,服务帐户无法访问我的个人电子邮件文件,只能访问那些特别 与服务帐户共享的文件?我是否也应该始终与我的服务帐户电子邮件地址共享每个文件?
代码:
def get_spreadsheet_data(name, spreadsheet_id, sheet_id, service_account_json_path, scope):
creds = ServiceAccountCredentials.from_json_keyfile_name(service_account_json_path, scope)
service = build('sheets', 'v4', credentials=creds)
sheets = service.spreadsheets()
# If name is not provided, generate it from spreadsheet_id
if not name:
a = sheets.get(
spreadsheetId=spreadsheet_id,
fields='sheets(properties(index,sheetId,title))'
).execute()
name = [sheet['properties']['title'] for sheet in a['sheets'] \
if int(sheet['properties']['sheetId']) == int(sheet_id)][0]
data_table = sheets.values().get(spreadsheetId=spreadsheet_id, range=name).execute()
data_values = data_table.get('values', [])
df = pd.DataFrame(data_values)
return df
出于文档目的发布此内容。
作为
服务帐户本身只能访问与其共享(或由其创建)的文件,而不能访问与您的常规帐户共享的文件。
如官方文档中所述:
Typically, an application uses a service account when the application uses Google APIs to work with its own data rather than a user's data.
如果您有 Workspace 帐户,则可以使用该服务帐户代表您域中的其他用户(例如您的常规帐户):请参阅 Delegating domain-wide authority to the service account 了解相关信息。否则,无法使用您的服务帐户访问用户文件。