App Engine 上的线程安全客户端库 (python)

Thread safe client lib on app engine (python)

我在 Google 的 git 存储库之一中找到了一些关于 bigquery 插入的示例代码。

https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/appengine/standard/bigquery/main.py

如果您看到 app.yaml 它说这段代码应该是线程安全的,但是如果我正在查看客户端库的文档 (https://developers.google.com/api-client-library/python/guide/thread_safety) 它应该不是线程安全的。我现在有点困惑,我的以下代码是否是线程安全的? 在 App Engine 标准环境中 运行。

import pprint

from googleapiclient.discovery import build
from oauth2client.client import GoogleCredentials


credentials = GoogleCredentials.get_application_default()

# Create the bigquery api client
service = build('bigquery', 'v2', credentials=credentials)

response = service.datasets().list(projectId='PROJECTID').execute()

pprint.pprint(response)

----更新---- 在蒂姆回答后,我将代码更改为以下内容。现在应该好了:

import pprint

from googleapiclient.discovery import build
from oauth2client.contrib.appengine import AppAssertionCredentials
import httplib2


credentials = AppAssertionCredentials(scope='https://www.googleapis.com/auth/bigquery')


# Create the bigquery api client
service = build('bigquery', 'v2')


def get():
    # authorize http object with client credentials
    http = credentials.authorize(httplib2.Http())
    response = service.datasets().list(projectId='PROJECTID').execute(http=http)

    pprint.pprint(response)

如果您阅读了您引用的文档,它会说

The google-api-python-client library is built on top of the httplib2 library, which is not thread-safe. Therefore, if you are running as a multi-threaded application, each thread that you are making requests from must have its own instance of httplib2.Http().

然后他们继续向您展示如何执行此操作。如果您按照说明进行操作,那么可以。

您的示例代码太简单,没有尝试文档中概述的内容

# Create a new Http() object for every request
  def build_request(http, *args, **kwargs):
    new_http = httplib2.Http()
    return apiclient.http.HttpRequest(new_http, *args, **kwargs)
  service = build('api_name', 'api_version', requestBuilder=build_request)

  # Pass in a new Http() manually for every request
  service = build('api_name', 'api_version')
  http = httplib2.Http()
  service.stamps().list().execute(http=http)

因此,如果您在线程情况下尝试您的代码,它将不是线程安全的。 如果您只是尝试使用 REPL 中的代码,那么我怀疑您是否处于线程状态。