code: def GetBatchJobDownloadUrlWhenReady(client, batch_job_id,
                                      max_poll_attempts=MAX_POLL_ATTEMPTS):
    
    batch_job = GetBatchJob(client, batch_job_id)
    if batch_job['status'] == 'CANCELED':
      raise Exception('Batch Job with ID "%s" was canceled before completing.'
                      % batch_job_id)
  
    poll_attempt = 0
  
    while (poll_attempt in range(max_poll_attempts) and
           batch_job['status'] in PENDING_STATUSES):
      sleep_interval = (30 * (2 ** poll_attempt) +
                        (random.randint(0, 10000) / 1000))
      print 'Batch Job not ready, sleeping for %s seconds.' % sleep_interval
      time.sleep(sleep_interval)
      batch_job = GetBatchJob(client, batch_job_id)
      poll_attempt += 1
  
      if 'downloadUrl' in batch_job:
        url = batch_job['downloadUrl']['url']
        print ('Batch Job with Id "%s", Status "%s", and DownloadUrl "%s" ready.'
               % (batch_job['id'], batch_job['status'], url))
        return url
  
    print ('BatchJob with ID "%s" is being canceled because it was in a pending '
           'state after polling %d times.' % (batch_job_id, max_poll_attempts))
    CancelBatchJob(client, batch_job)
docs: Retrieves the downloadUrl when the BatchJob is complete.
  
    Args:
      client: an instantiated AdWordsClient used to poll the BatchJob.
      batch_job_id: a long identifying the BatchJob to be polled.
      max_poll_attempts: an int defining the number of times the BatchJob will be
        checked to determine whether it has completed.
  
    Returns:
      A str containing the downloadUrl of the completed BatchJob.
  
    Raises:
      Exception: If the BatchJob hasn't finished after the maximum poll attempts
        have been made.