【问题标题】:Google API client (Python): is it possible to use BatchHttpRequest with ETag cachingGoogle API 客户端(Python):是否可以将 BatchHttpRequest 与 ETag 缓存一起使用
【发布时间】:2016-10-14 07:43:35
【问题描述】:

我正在使用 YouTube 数据 API v3。

是否有可能制作一个大的BatchHttpRequest(例如,参见here)并在httplib2 级别使用ETag 进行本地缓存(例如,参见here)?

ETags 对单个查询工作正常,我不知道它们是否对批处理请求也有用。

【问题讨论】:

    标签: python google-api-client httplib2 youtube-data-api


    【解决方案1】:

    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 lib 中评论的一种预感:

    """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 == 303redirect request
    2. ElSE -- response.status in [200, 203] and method in ["GET", "HEAD"]
    3. 或 -- if response.status == 304 and method == "GET"

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

    【讨论】:

    • @superciccio14 然后这样做http = httplib2.Http(cache=".cache")(根据来源:在最简单的情况下,您只需传入一个目录名称,然后将从该目录构建一个缓存)没有帮助吗?跨度>
    • 那么,如果您只是单个查询会发生什么? .cache 文件夹是否已创建?
    • @superciccio14 添加了最新发现。
    • @superciccio14 因为,BatchHttpRequest 将获取您的一批GET http 请求并跟踪POST + multipart/mixed 的所有请求。他们使用multipart/mixed 创建一批执行(如批量执行电子邮件附件下载)。所以,从这个意义上说,BatchHttpRequest 是在正确的轨道上。
    • @superciccio14 是的,绝对没有来自 httplib2 的 POST 缓存。这似乎是正确的。
    猜你喜欢
    • 2015-06-16
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多