Ringkasan

File Data Terstruktur (SDF) adalah file nilai yang dipisahkan koma (CSV) dengan format khusus yang digunakan untuk mengambil dan memperbarui data tentang resource Display & Video 360 secara massal. Melalui Display & Video 360 API, Anda dapat membuat dan mendownload SDF yang disesuaikan, sehingga Anda dapat mengambil data yang teratur dan difilter di resource Display & Video 360.

Panduan ini menjelaskan cara membuat operasi Download SDF, melacak operasi tersebut, dan mendownload SDF yang dihasilkan.

Informasi terkait format dan pembuatan versi SDF dapat ditemukan di dokumentasi referensi SDF.

Membuat tugas

SDF dibuat oleh operasi asinkron, yang disebut sdfdownloadtask. Saat membuat tugas ini, Anda menentukan parameter terkait SDF yang diinginkan. Hal ini dilakukan melalui metode sdfdownloadtasks.create. Subbagian berikut menjelaskan parameter yang dapat Anda tetapkan.

Menentukan versi

Format File Data Terstruktur diperbarui secara rutin dan terpisah dari Display & Video 360 API, dengan merilis versi baru dan menghentikan penggunaan versi sebelumnya secara rutin. Oleh karena itu, pengguna selalu disarankan untuk menggunakan SDF versi terbaru.

Anda menetapkan versi SDF dari SDF yang diinginkan menggunakan kolom version di isi permintaan. Jika tidak disetel atau disetel ke SDF_VERSION_UNSPECIFIED, tugas akan menggunakan versi SDF default dari resource pengiklan atau partner yang digunakan sebagai konteks konten SDF.

Menetapkan konteks

Anda dapat membuat SDF yang berisi data tentang resource apa pun yang tersedia untuk Anda, tetapi setiap SDF hanya dapat menampilkan konten dalam konteks satu partner atau pengiklan. Konteks ini ditentukan di isi permintaan oleh kolom partnerId atau advertiserId. Tepat satu dari dua kolom ini harus ditetapkan.

Hanya resource dalam konteks tertentu yang akan disertakan dalam SDF yang dihasilkan. Jika Anda mencoba memfilter menurut resource yang bukan milik partner atau pengiklan yang ditentukan, resource tersebut dan konten di bawahnya tidak akan disertakan dalam hasil. Jika hanya memfilter menurut resource yang tidak disertakan ini, file yang dihasilkan akan kosong. Mencoba memfilter menurut resource di luar konteks yang diberikan tidak akan menampilkan error, jadi pastikan untuk memeriksa apakah konteks Anda sudah benar.

Memilih filter yang tepat

Selain konteks yang ditetapkan di atas, Anda dapat memfilter lebih lanjut cakupan File Data Terstruktur yang dihasilkan dengan menentukan jenis file yang ingin dihasilkan dan resource atau grup resource tertentu yang ingin disertakan.

Ada tiga filter yang tersedia untuk sdfdownloadtask, yang masing-masing ditujukan untuk jenis spesifikasi tertentu. Anda hanya dapat menetapkan satu untuk satu sdfdownloadtask.

ParentEntityFilter

ParentEntityFilter adalah filter paling luas yang tersedia.

Dengan menggunakan kolom fileType, Anda dapat mencantumkan semua jenis file yang ingin Anda buat dengan tugas. Kolom ini wajib diisi, dan jika dibiarkan kosong atau disetel ke FILE_TYPE_UNSPECIFIED, sdfdownloadtask Anda akan selesai dengan error.

Dengan menggunakan kolom filterType dan filterIds, Anda dapat menyaring hasil lebih lanjut. filterType menentukan jenis resource yang akan difilter dan filterIds mengidentifikasi resource tersebut berdasarkan ID uniknya. SDF yang dihasilkan akan menyertakan resource yang diidentifikasi oleh fileType yang merupakan resource atau turunan dari resource yang diidentifikasi oleh filterType dan filterIds.

IdFilter

Filter IdFilter memfilter permintaan Anda agar hanya menyertakan resource yang diidentifikasi.

IdFilter memiliki kolom untuk setiap jenis SDF, kecuali Sumber Inventaris. Setiap kolom ini adalah daftar ID unik yang mengidentifikasi resource tertentu yang ingin Anda sertakan dalam SDF yang dihasilkan. ID yang diberikan harus berada dalam set konteks, tetapi tidak harus terkait langsung. Anda tidak perlu meminta kampanye tertentu untuk meminta item baris yang ada di dalamnya, dan sebaliknya. Satu-satunya jenis file yang dihasilkan adalah jenis file yang sesuai dengan resource yang diidentifikasi dalam IdFilter.

InventorySourceFilter

InventorySourceFilter hanya mengizinkan pemfilteran dan pendownloadan SDF yang berisi resource Sumber Inventaris. Filter ini adalah satu-satunya filter yang dapat Anda gunakan untuk mendapatkan informasi tentang resource Sumber Inventaris.

InventorySourceFilter memiliki satu kolom inventorySourceIds tempat Anda mengidentifikasi ID unik resource sumber inventaris yang ingin disertakan dalam SDF. Jika daftar yang diberikan ke inventorySourceIds kosong, semua sumber inventaris dalam konteks yang ditetapkan akan disertakan dalam SDF yang dihasilkan.

Buat permintaan

Setelah mengetahui parameter SDF yang diinginkan, Anda dapat membuat permintaan dan membuat sdfdownloadtask.

Berikut adalah contoh cara membuat sdfdownloadtask menggunakan ParentEntityFilter:

Java

// Create the filter structure
ParentEntityFilter parentEntityFilter = new ParentEntityFilter();
parentEntityFilter.setFileType(sdf-file-type-list);
parentEntityFilter.setFilterType(sdfFilterType);
parentEntityFilter.setFilterIds(filter-id-list);

// Configure the sdfdownloadtasks.create request
Sdfdownloadtasks.Create request =
   service
       .sdfdownloadtasks()
       .create(
           new CreateSdfDownloadTaskRequest()
               .setVersion(sdfVersion)
               .setAdvertiserId(advertiserId)
               .setParentEntityFilter(parentEntityFilter)
       );

// Create the sdfdownloadtask
Operation operationResponse = request.execute();

System.out.printf("Operation %s was created.\n",
   operationResponse.getName());

Python

# Configure the sdfdownloadtasks.create request
createSdfDownloadTaskRequest = {
    'version': sdf-version,
    'advertiserId': advertiser-id,
    'parentEntityFilter': {
        'fileType': sdf-file-type-list,
        'filterType': sdf-filter-type,
        'filterIds': filter-id-list
    }
}

# Create the sdfdownloadtask
operation = service.sdfdownloadtasks().create(
    body=createSdfDownloadTaskRequest).execute();

print("Operation %s was created." % operation["name"])

PHP

// Create the sdfdownloadtasks.create request structure
$createSdfDownloadTaskRequest =
    new Google_Service_DisplayVideo_CreateSdfDownloadTaskRequest();
$createSdfDownloadTaskRequest->setAdvertiserId(advertiser-id);
$createSdfDownloadTaskRequest->setVersion(sdf-version);

// Create and set the parent entity filter
$parentEntityFilter = new Google_Service_DisplayVideo_ParentEntityFilter();
$parentEntityFilter->setFileType(sdf-file-type-list);
$parentEntityFilter->setFilterType(sdf-filter-type);
if (!empty(filter-id-list)) {
    $parentEntityFilter->setFilterIds(filter-id-list);
}
$createSdfDownloadTaskRequest->setParentEntityFilter($parentEntityFilter);

// Call the API, creating the SDF Download Task.
$operation = $this->service->sdfdownloadtasks->create(
    $createSdfDownloadTaskRequest
);

printf('Operation %s was created.\n', $operation->getName());

Periksa permintaan Anda dan dapatkan jalur download

Saat Anda membuat sdfdownloadtask, objek operation akan ditampilkan. Operasi ini menampilkan status operasi pembuatan SDF asinkron Anda pada saat pembuatan. Anda dapat memeriksa operasi untuk melihat apakah operasi telah selesai dan siap didownload, atau apakah terjadi error, menggunakan metode sdfdownloadtasks.operations.get.

Setelah selesai, operasi yang ditampilkan akan memiliki kolom done yang tidak null. Operasi yang selesai akan menyertakan kolom response atau error. Jika ada, kolom error akan memiliki objek Status yang berisi kode error dan pesan, yang memberikan detail error yang terjadi. Jika ada kolom response, kolom tersebut akan memiliki objek dengan nilai resourceName yang mengidentifikasi file yang dihasilkan untuk didownload.

Berikut adalah contoh cara memeriksa permintaan Anda menggunakan backoff eksponensial:

Java

String operationName = operationResponse.getName();

// Configure the Operations.get request
Sdfdownloadtasks.Operations.Get operationRequest =
   service
       .sdfdownloadtasks()
       .operations()
       .get(operationName);

// Configure exponential backoff for checking the status of our operation
ExponentialBackOff backOff = new ExponentialBackOff.Builder()
   .setInitialIntervalMillis(5000) // setting initial interval to five seconds
   .setMaxIntervalMillis(300000)  // setting max interval to five minutes
   .setMaxElapsedTimeMillis(18000000) // setting max elapsed time to five hours
   .build();

while (operationResponse.getDone() == null) {
 long backoffMillis = backOff.nextBackOffMillis();
 if (backoffMillis == ExponentialBackOff.STOP) {
   System.out.printf("The operation has taken more than five hours to
       complete.\n");
   return;
 }
 Thread.sleep(backoffMillis);

 // Get current status of operation
 operationResponse = operationRequest.execute();
}

// Check if the operation finished with an error and return
if (operationResponse.getError() != null) {
 System.out.printf("The operation finished in error with code %s: %s\n",
     operationResponse.getError().getCode(), operationResponse.getError()
         .getMessage());
 return;
}

System.out.printf(
    "The operation completed successfully. Resource %s was created.\n",
    operationResponse.getResponse().get("resourceName").toString());

Python

# The following values control retry behavior while
# the report is processing.
# 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 Operations.get request
get_request = service.sdfdownloadtasks().operations().get(
  name=operation["name"]
)

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

  if "done" in operation:
    if "error" in operation:
      print("The operation finished in error with code %s: %s" % (
            operation["error"]["code"],
            operation["error"]["message"]))
    else:
      print("The operation completed successfully. Resource %s was created."
            % operation["response"]["resourceName"])
    break
  elif time.time() - start_time > max_retry_elapsed_time:
    print("Generation deadline exceeded.")

  sleep = next_sleep_interval(sleep)
  print("Operation still running, sleeping for %d seconds." % sleep)
  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))

PHP

// The following values control retry behavior
// while the task is processing.
// Minimum amount of time between polling requests. Defaults to 5 seconds.
$minRetryInterval = 5;
// Maximum amount of time between polling requests. Defaults to 5 minutes.
$maxRetryInterval = 300;
// Maximum amount of time to spend polling. Defaults to 5 hours.
$maxRetryElapsedTime = 18000;

$operationName = $operation->getName();

$sleepInterval = 0;
$startTime = time();

while (!$operation->getDone()) {
    if ($sleepInterval != 0) {
        printf(
            'The operation is still running, sleeping for %d seconds\n',
            $sleepInterval
        );
    }

    // Sleep before retrieving the SDF Download Task again.
    sleep($sleepInterval);

    // Call the API, retrieving the SDF Download Task.
    $operation = $this->service->sdfdownloadtasks_operations->get(
        $operation->getName()
    );

    // If the operation has exceeded the set deadline, throw an exception.
    if (time() - $startTime > $maxRetryElapsedTime) {
        printf('SDF download task processing deadline exceeded\n');
        throw new Exception(
            'Long-running operation processing deadline exceeded'
        );
    }

    // Generate the next sleep interval using exponential backoff logic.
    $sleepInterval = min(
        $maxRetryInterval,
        rand(
            max($minRetryInterval, $previousSleepInterval),
            max($minRetryInterval, $previousSleepInterval * 3)
        )
    );
}

// If the operation finished with an error, throw an exception.
if($operation->getError() !== null) {
    $error = $operation->getError();
    printf(
        'The operation finished in error with code %s: %s\n',
        $error->getCode(),
        $error->getMessage()
    );
    throw new Exception($error->getMessage());
}

// Print successfully generated resource.
$response = $operation->getResponse();
printf(
    'The operation completed successfully. Resource %s was '
        . 'created. Ready to download.\n',
    $response['resourceName']
);