Tổng quan

Tệp dữ liệu có cấu trúc (SDF) là các tệp có giá trị được phân tách bằng dấu phẩy (CSV) có định dạng đặc biệt, dùng để truy xuất và cập nhật hàng loạt dữ liệu về tài nguyên Display & Video 360. Thông qua Display & Video 360 API, bạn có thể tạo và tải các SDF tuỳ chỉnh xuống để truy xuất dữ liệu được sắp xếp và đã lọc trên các tài nguyên của Display & Video 360.

Hướng dẫn này mô tả cách tạo thao tác Tải xuống SDF, theo dõi thao tác đó và tải xuống SDF thu được.

Bạn có thể xem thông tin về định dạng và phiên bản SDF trong tài liệu tham khảo SDF.

Tạo việc cần làm

SDF được tạo bằng một thao tác không đồng bộ có tên là sdfdownloadtask. Khi tạo tác vụ này, bạn sẽ xác định các tham số liên quan đến SDF mà bạn muốn. Bạn có thể thực hiện việc này thông qua phương thức sdfdownloadtasks.create. Các tiểu mục sau đây mô tả các tham số bạn có thể thiết lập.

Chỉ định một phiên bản

Định dạng Tệp dữ liệu có cấu trúc thường xuyên được cập nhật độc lập với API Display & Video 360, trong đó có các phiên bản mới được phát hành và các phiên bản cũ thường xuyên không dùng nữa. Vì lý do này, người dùng luôn nên sử dụng phiên bản SDF mới nhất.

Bạn đặt phiên bản SDF của SDF mà bạn muốn bằng cách sử dụng trường version trong nội dung yêu cầu. Nếu bạn không đặt hoặc đặt thành SDF_VERSION_UNSPECIFIED, thì tác vụ sẽ sử dụng phiên bản SDF mặc định của tài nguyên nhà quảng cáo hoặc đối tác được dùng làm ngữ cảnh của nội dung SDF.

Đặt bối cảnh

Bạn có thể tạo một SDF chứa dữ liệu về mọi tài nguyên có sẵn cho bạn, nhưng mọi SDF riêng lẻ chỉ có thể trả về nội dung trong bối cảnh của một đối tác hoặc nhà quảng cáo. Ngữ cảnh này được xác định trong nội dung yêu cầu bằng trường partnerId hoặc advertiserId. Bạn phải đặt chính xác một trong hai trường này.

Chỉ những tài nguyên trong ngữ cảnh nhất định mới được đưa vào SDF thu được. Nếu bạn cố gắng lọc theo một tài nguyên không thuộc sở hữu của đối tác hoặc nhà quảng cáo được chỉ định, thì cả tài nguyên và nội dung trong đó sẽ không được đưa vào kết quả. Nếu chỉ lọc theo những tài nguyên không được đưa vào này, thì các tệp kết quả sẽ trống. Việc cố gắng lọc theo các tài nguyên bên ngoài ngữ cảnh nhất định sẽ không trả về lỗi, vì vậy, hãy nhớ kiểm tra xem ngữ cảnh của bạn có chính xác hay không.

Chọn bộ lọc phù hợp

Ngoài bối cảnh được đặt ở trên, bạn có thể lọc thêm phạm vi của Tệp dữ liệu có cấu trúc đã tạo bằng cách chỉ định loại tệp mà bạn muốn tạo và tài nguyên hoặc nhóm tài nguyên cụ thể mà bạn muốn đưa vào.

Có ba bộ lọc có sẵn cho sdfdownloadtask, mỗi bộ lọc phù hợp với một loại thông số kỹ thuật cụ thể. Bạn chỉ có thể gán một mã cho một sdfdownloadtask.

ParentEntityFilter

ParentEntityFilter là bộ lọc rộng nhất trong số các bộ lọc có sẵn.

Khi sử dụng trường fileType, bạn có thể liệt kê tất cả loại tệp mong muốn mà bạn muốn tạo bằng tác vụ của mình. Đây là điều bắt buộc và nếu để trống hoặc đặt thành FILE_TYPE_UNSPECIFIED, sdfdownloadtask của bạn sẽ hoàn tất do lỗi.

Bạn có thể tinh chỉnh thêm kết quả của mình bằng cách sử dụng các trường filterTypefilterIds. filterType chỉ định loại tài nguyên cần lọc theo và filterIds xác định các tài nguyên đó theo mã nhận dạng duy nhất. Các SDF thu được sẽ bao gồm các tài nguyên được xác định bởi fileType. Đó là tài nguyên hoặc tài nguyên con của các tài nguyên được filterTypefilterIds xác định.

IdFilter

IdFilter lọc yêu cầu của bạn để chỉ bao gồm những tài nguyên đã được xác định.

IdFilter có một trường cho mọi loại SDF, ngoại trừ Nguồn khoảng không quảng cáo. Mỗi trường trong số này là một danh sách mã nhận dạng duy nhất xác định những tài nguyên cụ thể bạn muốn đưa vào SDF đã tạo. Các mã nhận dạng được cung cấp phải nằm trong ngữ cảnh đã đặt, nhưng không cần phải liên quan trực tiếp. Bạn không cần yêu cầu một chiến dịch cụ thể để yêu cầu mục hàng có trong chiến dịch đó và ngược lại. Các loại tệp duy nhất được tạo sẽ là những loại tương ứng với tài nguyên được xác định trong IdFilter.

InventorySourceFilter

InventorySourceFilter chỉ cho phép lọc và tải xuống các SDF có chứa tài nguyên Nguồn khoảng không quảng cáo. Đây là bộ lọc duy nhất bạn có thể sử dụng để lấy thông tin về tài nguyên Nguồn khoảng không quảng cáo.

InventorySourceFilter có một trường inventorySourceIds duy nhất giúp bạn xác định các mã nhận dạng duy nhất của tài nguyên nguồn khoảng không quảng cáo mà bạn muốn đưa vào SDF. Nếu danh sách bạn cung cấp cho inventorySourceIds trống, thì tất cả nguồn khoảng không quảng cáo trong ngữ cảnh đã đặt sẽ được đưa vào SDF đã tạo.

Tạo yêu cầu

Sau khi biết các tham số của SDF mong muốn, bạn có thể tạo yêu cầu và tạo sdfdownloadtask.

Sau đây là ví dụ về cách tạo sdfdownloadtask bằng 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"])

1.199

// 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());

Kiểm tra yêu cầu của bạn và nhận đường dẫn tải xuống

Khi bạn tạo sdfdownloadtask, một đối tượng phép toán sẽ được trả về. Thao tác này cho biết trạng thái của hoạt động tạo SDF không đồng bộ tại thời điểm tạo. Bạn có thể kiểm tra thao tác của mình để xem thao tác đã hoàn tất và sẵn sàng để tải xuống hay đã xảy ra lỗi, bằng cách sử dụng phương thức sdfdownloadtasks.operations.get.

Sau khi hoàn tất, thao tác được trả về sẽ có một trường done khác rỗng. Thao tác hoàn tất sẽ bao gồm trường response hoặc error. Nếu có, trường error sẽ có đối tượng Status chứa mã lỗithông báo cho biết thông tin chi tiết về lỗi đã xảy ra. Nếu có trường response, trường này sẽ có một đối tượng với giá trị resourceName xác định tệp đã tạo để tải xuống.

Dưới đây là ví dụ về cách kiểm tra yêu cầu của bạn bằng thuật toán thời gian đợi luỹ thừa:

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))

1.199

// 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']
);