Google API 客户端(Python):是否可以将 BatchHttpRequest 与 ETag 缓存一起使用

Google API client (Python): is it possible to use BatchHttpRequest with ETag caching

我正在使用 YouTube 数据 API v3。

是否可以做大BatchHttpRequest(例如,参见here) and also to use ETags for local caching at the httplib2 level (e.g., see here)?

ETags 适用于单个查询,我不知道它们是否也适用于批量请求。

TL;DR:

  • BatchHttpRequest 不能与缓存一起使用

在这里:

先看看初始化的方法BatchHttpRequest:

from apiclient.http import BatchHttpRequest

def list_animals(request_id, response, exception):
  if exception is not None:
    # Do something with the exception
    pass
  else:
    # Do something with the response
    pass

def list_farmers(request_id, response):
  """Do something with the farmers list response."""
  pass

service = build('farm', 'v2')

batch = service.new_batch_http_request()

batch.add(service.animals().list(), callback=list_animals)
batch.add(service.farmers().list(), callback=list_farmers)


batch.execute(http=http)

其次让我们看看如何使用ETags

from google.appengine.api import memcache
http = httplib2.Http(cache=memcache)

现在让我们分析一下:

观察 BatchHttpRequest 示例的最后一行:batch.execute(http=http),现在检查 source code 执行,它调用 _refresh_and_apply_credentials,它应用我们传递给它的 http 对象。

def _refresh_and_apply_credentials(self, request, http):
    """Refresh the credentials and apply to the request.
    Args:
      request: HttpRequest, the request.
      http: httplib2.Http, the global http object for the batch.
    """
    # For the credentials to refresh, but only once per refresh_token
    # If there is no http per the request then refresh the http passed in
    # via execute()

这意味着,接受 http 的执行调用可以传递您创建的 ETag http:

http = httplib2.Http(cache=memcache)
# This would mean we would get the ETags cached http
batch.execute(http=http)

更新 1:

也可以尝试使用自定义对象:

from googleapiclient.discovery_cache import DISCOVERY_DOC_MAX_AGE
from googleapiclient.discovery_cache.base import Cache
from googleapiclient.discovery_cache.file_cache import Cache as FileCache

custCache = FileCache(max_age=DISCOVERY_DOC_MAX_AGE)
http = httplib2.Http(cache=custCache)
# This would mean we would get the ETags cached http
batch.execute(http=http)

因为,这只是对 http2 库中评论的预感:

"""If 'cache' is a string then it is used as a directory name for
        a disk cache. Otherwise it must be an object that supports the
        same interface as FileCache.

结论更新 2:

再次验证google-api-python源码后发现,BatchHttpRequest是用'POST'请求修复的,有一个multipart/mixed;.. - source code 的内容类型。

提供一个事实的线索,BatchHttpRequest 对于 POST 数据是有用的,然后在后面进行处理。

现在,牢记这一点,观察 httplib2 request 方法使用的内容:_updateCache 仅当满足以下条件时:

  1. 请求在 ["GET", "HEAD"]response.status == 303 中或者是 redirect request
  2. 其他 -- response.status in [200, 203] and method in ["GET", "HEAD"]
  3. 或--if response.status == 304 and method == "GET"

这意味着,BatchHttpRequest不能与缓存一起使用。