Poll task status

Structured Data Files don't generate instantaneously. Display & Video 360 might take anywhere from a few seconds to hours to generate your SDFs.

To determine if your task is finished, regularly retrieve the operation using sdfdownloadtasks.operations.get and check if the done field is True and the task is finished. This process is known as "polling."

If the task is finished, either the response or error field is set. If the error field is populated, the task failed and details about the failure are available in the resulting Status object. If the response field is populated, Display & Video 360 successfully generated the SDFs. Download the resulting files from the location provided in response.resourceName.

An inefficient polling implementation that checks on a long-running report consumes a lot of your API request quota. To limit retries and conserve quota, use exponential backoff.

Here's how to poll a SDF download operation using exponential backoff:

# Provide the name of the sdfdownloadtask operation.
operation_name = operation-name

# Set the following values that control retry behavior while the operation
# is running.
# Minimum amount of time between polling requests. Defaults to 5 seconds.
min_retry_interval = 5
# Maximum amount of time between polling requests. Defaults to 5 minutes.
max_retry_interval = 5 * 60
# Maximum amount of time to spend polling. Defaults to 5 hours.
max_retry_elapsed_time = 5 * 60 * 60

# Configure the sdfdownloadtasks.operations.get request.
get_request = service.sdfdownloadtasks().operations().get(operation_name)

sleep = 0

start_time = time.time()
while True:
  # Get current status of the report.
  operation = get_request.execute()

  if "done" in operation:
    if "error" in operation:
      print(
        f'The operation finished in error with code '
        f'{operation["error"]["code"]}: {operation["error"]["message"]}')
    else:
      print(
        f'The operation completed successfully. The resulting files can be '
        f'downloaded at {operation["response"]["resourceName"]}.')
    break
  elif time.time() - start_time > max_retry_elapsed_time:
    print("SDF generation deadline exceeded.")
    break

  sleep = next_sleep_interval(sleep)
  print(
    f'Operation {operation_name} is still running, sleeping for '
    f'{sleep} seconds.')
  time.sleep(sleep)

def next_sleep_interval(previous_sleep_interval):
  """Calculates the next sleep interval based on the previous."""
  min_interval = previous_sleep_interval or min_retry_interval
  max_interval = previous_sleep_interval * 3 or min_retry_interval
  return min(max_retry_interval, random.randint(min_interval, max_interval))