Google API Client for Python. Batch requests: how to access to a specific request in the callback

3.9k views Asked by At

According to official doc, you can make batch request through Google API Client Libraries for Python. Here, there is an example

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)

Is there a way to access to the request in the callback. E.g., print the request (not the request_id) if there is an exception?

2

There are 2 answers

0
Sean On

In case it helps anyone - I'm using google-api-python-client==2.65.0 and the call back is passed differently - it is specified like this:

def list_animals(request_id, response, exception=None):
  if exception is None:
    original_request = requests[request_id]
    # process here...

batch = service.new_batch_http_request(callback=list_animals)

batch.add(service.animals().list())
batch.add(service.farmers().list())
batch.execute()
2
smstone On

I ran into this same issue, as I needed the original request for using compute.instances().aggregatedList_next() function.

I ended up passing a unique request_id to batch.add() and created a dictionary to keep track of the original requests that were made. Then within the callback, I referenced that dictionary and pulled out the request by using the unique request_id.

So I did something along the following:

requests = {}
project = 'example-project'
batch = service.new_batch_http_request(callback=callback_callable)
new_request = compute.instances().aggregatedList(project=project)
requests[project] = new_request
batch.add(new_request, request_id=project)

Within the callable function:

def callback_callable(self, request_id, response, exception):
    original_request = requests[request_id]

Note that the value passed to the request_id needs to be a string. If an int is passed it will raise a TypeError quote_from_bytes() expected bytes.

Hope this helps someone!