为 BigQuery Python CLI 设置 GOOGLE_APPLICATION_CREDENTIALS

Setting GOOGLE_APPLICATION_CREDENTIALS for BigQuery Python CLI

我正在尝试使用 Python 通过 BigQuery API 连接到 Google BigQuery。

我正在关注此页面: https://cloud.google.com/bigquery/bigquery-api-quickstart

我的代码如下:

import os
import argparse

from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.client import GoogleCredentials

GOOGLE_APPLICATION_CREDENTIALS = './Peepl-cb1dac99bdc0.json'

def main(project_id):
    # Grab the application's default credentials from the environment.
    credentials = GoogleCredentials.get_application_default()
    print(credentials)
    # Construct the service object for interacting with the BigQuery API.
    bigquery_service = build('bigquery', 'v2', credentials=credentials)

    try:
        query_request = bigquery_service.jobs()
        query_data = {
            'query': (
                'SELECT TOP(corpus, 10) as title, '
                'COUNT(*) as unique_words '
                'FROM [publicdata:samples.shakespeare];')
        }

        query_response = query_request.query(
            projectId=project_id,
            body=query_data).execute()

        print('Query Results:')
        for row in query_response['rows']:
            print('\t'.join(field['v'] for field in row['f']))

    except HttpError as err:
        print('Error: {}'.format(err.content))
        raise err


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('project_id', help='Your Google Cloud Project ID.')

    args = parser.parse_args()

    main(args.project_id)

但是,当我通过终端 运行 这段代码时,出现以下错误:

oauth2client.client.ApplicationDefaultCredentialsError: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.

正如您在代码中看到的,我已尝试根据错误中的 link 设置 GOOGLE_APPLICATION_CREDENTIALS。但是,错误仍然存​​在。有谁知道问题是什么?

提前谢谢你。

错误消息 https://developers.google.com/identity/protocols/application-default-credentials 中提供的 link 表示将 环境变量 设置为指向包含 JSON 服务凭证。看起来您设置了一个 Python 变量。尝试将终端的环境变量设置为指向正确的文件。

另一种方法是当您不在 GCE 容器中时 运行 明确使用一些其他凭据,例如 oauth2client.client.SignedJwtAssertionCredentials 并将其直接指向您的客户端机密,这样您就没有通过环境变量间接。

它正在寻找本地 UNIX(或其他)环境中的环境变量,而不是 python 脚本中的变量。

您可以通过打开终端或 cygwin 并执行以下操作之一来设置它:

export GOOGLE_APPLICATION_CREDENTIALS='/path/to/your/client_secret.json'

在您的终端中输入它来设置这个 session

的变量

在 UNIX 中输入 nano ~/.bashrc 打开你的 .bashrc 文件,如果你看到 header:

,将此行添加到用户特定别名下
GOOGLE_APPLICATION_CREDENTIALS="/full/path/to/your/client_secret.json"

然后通过键入 source ~/.bashrc 重新加载它并通过尝试 echo $GOOGLE_APPLICATION_CREDENTIALS 确认它已设置。如果它 returns 路径,你就很好。

正在寻找环境变量。但是我能够通过使用应用程序默认凭据在 Windows 平台上解决这个问题。

我遵循的步骤:

  • 已安装 Google SDK
  • 然后执行 gcloud init 步骤来指定我的默认凭据和默认项目,您可以根据需要更改这些项目。 gcloud 可执行文件可以在您选择安装 Google SDK 的 bin 目录中找到。
  • 成功提供凭据后,您可以在C:\Users\"yourusername"\AppData\Roaming\gcloud\legacy_credentials\"youremail"位置签到 .您可以在那里找到以 JSON 格式存储的凭据。

它帮助我解决了错误。

首先-感谢您提供的代码-这非常有用。 我还建议直接在您的代码中添加设置环境变量——而不是为您工作的每个环境都设置它。 您可以使用以下代码:

import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "path_to_your_.json_credential_file"

我发现这在需要不同凭据的不同项目之间切换时很有用。

如果想在不设置环境变量的情况下使用不同的凭证文件,可以使用以下代码:

from oauth2client import service_account
from apiclient.discovery import build
import json

client_credentials = json.load(open("<path to .json credentials>"))

credentials_token = service_account._JWTAccessCredentials.from_json_keyfile_dict(client_credentials)

bigquery_service = build('bigquery', 'v2', credentials=credentials_token)
query_request = bigquery_service.jobs()
query_data = {
    'query': (
            'SELECT TOP(corpus, 10) as title, '
            'COUNT(*) as unique_words '
            'FROM [publicdata:samples.shakespeare];')
    }

query_response = query_request.query(
           projectId=project_id,
           body=query_data).execute()

print('Query Results:')
for row in query_response['rows']:
    print('\t'.join(field['v'] for field in row['f']))

我不确定 BigQuery,但我正在使用 Google Data Store 进行保存。如果您在 mac 中安装了 gcloud sdk,您可以尝试 运行 这个命令

gcloud auth application-default login

GOOGLE_APPLICATION_CREDENTIALS 未找到 C# 的错误解决方案

System.Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS",@"C:\apikey.json");
string Pathsave = System.Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");

注:oauth2client is deprecated, instead of GoogleCredentials.get_application_default() you can use google.auth.default()。首先安装软件包:

pip install google-auth

在您的具体示例中,我看到您从代码中知道 JSON 文件的位置。您可以 use a service account directly with the google.oauth2.service_account 模块代替默认凭据(来自环境变量)。

credentials = google.oauth2.service_account.Credentials.from_service_account_file(
    './Peepl-cb1dac99bdc0.json',
    scopes=['https://www.googleapis.com/auth/cloud-platform'])

您可以像当前一样使用此凭据文件,方法是将它们传递给 googleapiclient.discovery.build or if you are using the google-cloud-bigquery library, pass the credentials to the google.cloud.bigquery.Client 构造函数。

您可以使用 from_service_account_json() 创建具有服务帐户凭据的客户端:

from google.cloud import bigquery
bigqueryClient = bigquery.Client.from_service_account_json('/path/to/keyfile.json')

在您的项目文件夹中,只需键入:

set GOOGLE_APPLICATION_CREDENTIALS='\path\key.json'
  • 从命令行导出 Google 凭据 JSON:
    export GOOGLE_APPLICATION_CREDENTIALS='\path\key.json'
    希望一切顺利

如果出现无法在文件集中提供凭据的情况 GOOGLE_APPLICATION_CREDENTIALS='\path\key.json'

  1. 由于服务帐号是JSON并且包含双引号字符,将每个双引号替换为\"
  2. 用双引号将完整的 JSON 括起来
  3. 将每个 \n 替换为 \n(在 linux 上)\\n(在 mac 上)

如果您将服务帐户中的上述更改导出为变量,那么它应该会被正确记录。

尝试echo %variable_name确认它是否好看。

除了使用 GOOGLE_APPLICATION_CREDENTIALS(已经在一堆答案中描述)之外,还有一种方法可以将生成的 json 凭据设置为默认服务帐户:

gcloud auth activate-service-account --key-file=<path to your generated json file>

这将激活默认帐户(并根据提供的json文件设置凭据)而无需显式设置GOOGLE_APPLICATION_CREDENTIALS,并且在不修改的情况下重新登录或重启后仍将激活。 bashrc.

我认为这里还没有提到另一种解决方法。 google.oauth2.service_account.Credentials 对象提供 from_service_account_info 方法(参见此处:https://github.com/googleapis/google-auth-library-python/blob/main/google/oauth2/service_account.py)。

所以你可以在你的环境中设置任何你想要的变量并读入它并将它传递给函数,就像这样:

your_data = { 
"type": os.environ.get('YOUR_ENV_VAR'),
"project_id": os.environ.get('YOUR_ENV_VAR'),
"private_key_id": os.environ.get('YOUR_ENV_VAR'),
#... and so on with all the required Google variables....
}
your_credentials = service_account.Credentials.from_service_account_info(your_data, scopes=your_scopes)
service = discovery.build(api_name, api_version, credentials=your_credentials)

我基本上从我的 google keyfile.json 中获取了所有数据并将它们存储在环境中并执行了上述操作。这样你就永远不需要将你的 keyfile.json 放在你的代码附近的任何地方,或者更糟的是,将它上传到某个地方 public。基本上就是这样。祝你好运!

PS:我也忘了提这个,这可能会帮助 运行 遇到和我一样的问题的人。虽然上面的代码在开发中应该可以正常工作,但在某些生产环境中 \n 不会被解释为换行。相反,它将保留在私钥中。将以上所有内容放入 try 语句中,如果出现错误:“无法检测到密钥”,那么这很可能是问题所在。在这种情况下,您需要将所有 \\n 替换为 \n ,类似于 Sumit Agrawal 所建议的,但有点像其他一路走来。这是因为在某些环境中,对于新行指示(例如 \n)会自动添加 \,以便在有意义的情况下保持它们的原样。所以你必须基本上撤消这个。

您只需对上面的其中一行执行以下操作: "private_key": os.environ.get('YOUR_ENV_VAR').replace('\n', '\n'),

但再次尝试将它们打印到日志文件/控制台以查看它们的实际外观。如果字符串中有任何 \n,您知道您需要按照说明清理或转换它们。祝你好运!