Descripción general

Los archivos de datos estructurados (SDF) son archivos de valores separados por comas (CSV) con formato especial que se usan para recuperar y actualizar datos de los recursos de Display & Video 360 de forma masiva. Mediante la API de Display & Video 360, puedes generar y descargar SDF personalizados, lo que te permite recuperar datos organizados y filtrados en tus recursos de Display & Video 360.

En esta guía, se describe cómo crear una operación de descarga de SDF, hacer un seguimiento de esa operación y descargar los SDF resultantes.

Puedes encontrar información sobre el formato y el control de versiones de SDF en la documentación de referencia de SDF.

Cómo crear una tarea

Los SDF se generan mediante una operación asíncrona llamada sdfdownloadtask. Cuando crees esta tarea, definirás los parámetros respecto a los SDF deseados. Esto se hace con el método sdfdownloadtasks.create. En las siguientes subsecciones, se describen los parámetros que puedes configurar.

Cómo especificar una versión

El formato de archivo de datos estructurados se actualiza con regularidad independientemente de la API de Display & Video 360, con versiones nuevas y obsoletas con regularidad. Por este motivo, siempre se recomienda que los usuarios usen la versión más reciente de SDF.

Configura la versión de SDF del SDF deseado con el campo version del cuerpo de la solicitud. Si no se establece o se establece en SDF_VERSION_UNSPECIFIED, la tarea usará la versión predeterminada de SDF del recurso de anunciante o socio que se usa como contexto del contenido de SDF.

Establece el contexto.

Puedes generar un SDF que contenga datos de cualquier recurso disponible, pero cualquier SDF individual solo puede mostrar contenido dentro del contexto de un solo socio o anunciante. Este contexto se define en el cuerpo de la solicitud mediante el campo partnerId o advertiserId. Se debe establecer exactamente uno de estos dos campos.

Solo se incluirán en el SDF resultante los recursos dentro del contexto dado. Si intentas filtrar por un recurso que no es propiedad del socio o anunciante especificado, ni este ni su contenido se incluirán en los resultados. Si solo filtras por estos recursos no incluidos, los archivos resultantes estarán vacíos. Si intentas filtrar por recursos fuera del contexto dado, no se mostrará un error, por lo que debes asegurarte de verificar que tu contexto sea correcto.

Elige el filtro correcto

Además del contexto establecido anteriormente, puedes filtrar aún más el alcance de tus archivos de datos estructurados generados si especificas los tipos de archivos que deseas generar y los recursos o la familia de recursos específicos que deseas incluir.

Hay tres filtros disponibles para una sdfdownloadtask, cada uno dirigido a un tipo de especificación en particular. Solo puedes asignar uno a una única sdfdownloadtask.

ParentEntityFilter

ParentEntityFilter es el más amplio de los filtros disponibles.

En el campo fileType, puedes enumerar todos los tipos de archivos que deseas generar con tu tarea. Esto es obligatorio y, si se deja vacío o se establece en FILE_TYPE_UNSPECIFIED, tu sdfdownloadtask se completará por error.

Con los campos filterType y filterIds, puedes definir mejor los resultados. filterType especifica el tipo de recursos con el que se filtrará y filterIds identifica esos recursos por su ID único. Los SDF resultantes incluirán los recursos identificados por fileType que son los recursos o elementos secundarios de los recursos identificados por filterType y filterIds.

IdFilter

IdFilter filtra tu solicitud para incluir solo los recursos identificados.

IdFilter tiene un campo para cada tipo de SDF, excepto la fuente de inventario. Cada uno de estos campos es una lista de ID únicos que identifican los recursos específicos que deseas incluir en tu SDF generado. Los IDs proporcionados deben estar dentro del conjunto de contexto, pero no es necesario que estén relacionados de forma directa. No es necesario que solicites una campaña en particular para solicitar la línea de pedido que contiene, y viceversa. Los únicos tipos de archivos generados serán aquellos correspondientes a los recursos identificados en el IdFilter.

InventorySourceFilter

InventorySourceFilter solo permite filtrar y descargar SDF que contienen recursos de fuentes de inventario. Es el único filtro que puedes usar para obtener información sobre los recursos de tu fuente de inventario.

InventorySourceFilter tiene un campo inventorySourceIds único en el que identificas los ID únicos de los recursos de fuente de inventario que deseas incluir en tu SDF. Si la lista proporcionada a inventorySourceIds está vacía, todas las fuentes de inventario en el contexto establecido se incluirán en el SDF generado.

Haz una solicitud

Una vez que conozcas los parámetros del SDF deseado, puedes construir la solicitud y crear el sdfdownloadtask.

Este es un ejemplo de cómo crear un sdfdownloadtask con un 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());

Revisa tu solicitud y obtén la ruta de descarga

Cuando creas un sdfdownloadtask, se muestra un objeto operation. Esta operación representa el estado de la operación de generación de SDF asíncrona en el momento de la creación. Puedes verificar la operación a fin de ver si se completó y si está lista para descargarse, o si mostró un error, mediante el método sdfdownloadtasks.operations.get.

Una vez finalizada, la operación que se muestra tendrá un campo done no nulo. La operación finalizada incluirá un campo response o error. Si está presente, el campo error tendrá un objeto Status que contiene un código de error y un mensaje, que proporciona detalles del error que se produjo. Si el campo response está presente, tendrá un objeto con un valor resourceName que identifica el archivo generado para su descarga.

Este es un ejemplo de cómo verificar tu solicitud con la retirada exponencial:

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