סקירה כללית

קובצי נתונים מובְנים (SDF) הם קבצים בפורמט מיוחד המופרדים בפסיקים (CSV), שמשמשים לאחזור ולעדכון של נתונים לגבי משאבי Display & Video 360 בכמות גדולה. ב-Display & Video 360 API אפשר ליצור ולהוריד SDF בהתאמה אישית, וכך לאחזר נתונים מאורגנים ומסוננים במשאבי Display & Video 360.

במדריך הזה מוסבר איך ליצור פעולת הורדה של SDF, לעקוב אחרי הפעולה הזו ולהוריד את מפתחות ה-SDF שמתקבלים.

במשאבי העזרה בנושא SDF תוכלו למצוא מידע על הפורמט וניהול הגרסאות של SDF.

צור משימה

SDFs נוצרים על ידי פעולה אסינכרונית, הנקראת sdfdownloadtask. כשיוצרים את המשימה הזו, מגדירים את הפרמטרים של SDF הרצוי. ניתן לעשות זאת באמצעות השיטה sdfdownloadtasks.create. בקטעי המשנה הבאים מתוארים הפרמטרים שאפשר להגדיר.

ציון גרסה

הפורמט של קובץ הנתונים המובְנים מתעדכן באופן קבוע, בנפרד מ-Display & Video 360 API, וגרסאות חדשות שהושקו וגרסאות ישנות יוצאות משימוש באופן קבוע. לכן, תמיד מומלץ למשתמשים להשתמש בגרסה העדכנית ביותר של SDF.

מגדירים את גרסת ה-SDF של ה-SDF הרצוי באמצעות השדה version בגוף הבקשה. אם המדיניות לא מוגדרת או מוגדרת לערך SDF_VERSION_UNSPECIFIED, במשימה ייעשה שימוש בגרסת ברירת המחדל של SDF של משאב המפרסם או השותף, שמשמשת כהקשר של תוכן ה-SDF.

מגדירים את ההקשר

אפשר ליצור SDF שמכיל נתונים על כל המשאבים שזמינים לכם, אבל כל SDF יחיד יכול להחזיר תוכן רק בהקשר של שותף או מפרסם יחיד. ההקשר מוגדר בגוף הבקשה באמצעות השדה partnerId או השדה advertiserId. צריך להגדיר בדיוק אחד משני השדות האלה.

רק משאבים בהקשר הנתון ייכללו ב-SDF שיתקבל. אם תנסו לסנן לפי משאב שאינו בבעלות השותף או המפרסם שצוינו, הוא וגם התוכן שמתחתיו לא ייכללו בתוצאות. אם מסננים רק לפי המשאבים שלא כלולים, הקבצים שיתקבלו יהיו ריקים. אם תנסו לסנן לפי משאבים מחוץ להקשר הנתון, לא תוצג הודעת שגיאה, לכן חשוב לבדוק שההקשר נכון.

בחירת הפילטר הנכון

בנוסף להקשר שלמעלה, אפשר להמשיך לסנן את ההיקף של קובצי הנתונים המובְנים שאתם יוצרים על ידי ציון סוגי הקבצים שרוצים ליצור והמשאבים הספציפיים או משפחת המשאבים שרוצים לכלול.

יש שלושה מסננים לsdfdownloadtask, שכל אחד מהם מתאים לסוג מסוים של מפרט. אפשר להקצות רק קוד אחד לsdfdownloadtask אחד.

ParentEntityFilter

המסנן ParentEntityFilter הוא המסנן הרחב ביותר מבין המסננים הזמינים.

בשדה fileType אפשר לפרט את כל סוגי הקבצים שרוצים ליצור במשימה. זהו שדה חובה. אם משאירים אותו ריק או מוגדר לערך FILE_TYPE_UNSPECIFIED, השלמה של sdfdownloadtask תתבצע בטעות.

בעזרת השדות filterType ו-filterIds תוכלו לצמצם עוד יותר את התוצאות. השדה filterType מציין את סוג המשאבים שלפיו רוצים לסנן את המשאבים האלה, ו-filterIds מזהה את המשאבים האלה לפי המזהה הייחודי שלהם. משאבי ה-SDF שיתקבלו יכללו את המשאבים שזוהו על ידי fileType, שהם המשאבים או הצאצאים של המשאבים שזוהו על ידי filterType ו-filterIds.

IdFilter

IdFilter מסנן את הבקשה כך שיכלול רק את המשאבים שזוהו.

בשדה IdFilter יש שדה לכל סוג של SDF, מלבד מקור המלאי. בכל אחד מהשדות האלה מופיעה רשימה של מזהים ייחודיים שמזהים את המשאבים הספציפיים שאתם רוצים לכלול ב-SDF שנוצר. המזהים שאתם מספקים חייבים להופיע בהקשר שהוגדר, אבל לא בהכרח בקשר ישיר. לא צריך לבקש קמפיין מסוים כדי לבקש פריט שהוא מכיל, ולהיפך. סוגי הקבצים היחידים שייווצרו יהיו מאלה שתואמים למשאבים שצוינו ב-IdFilter.

InventorySourceFilter

באמצעות InventorySourceFilter אפשר לבצע רק סינון והורדה של SDFs שמכילים משאבים של מקור מלאי. זה המסנן היחיד שבו אפשר להשתמש כדי להציג מידע על המשאבים של מקור המלאי.

בשדה InventorySourceFilter יש שדה inventorySourceIds יחיד שבו מציינים את המזהים הייחודיים של משאבי המקור של מלאי שטחי הפרסום שאתם רוצים לכלול ב-SDF. אם הרשימה שסופקה ל-inventorySourceIds ריקה, כל מקורות המלאי בהקשר שהוגדר ייכללו ב-SDF שנוצר.

יצירת בקשה

אחרי שמכירים את הפרמטרים של ה-SDF הרצוי, אפשר ליצור את הבקשה וליצור את sdfdownloadtask.

דוגמה ליצירה של sdfdownloadtask באמצעות 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());

בדיקת הבקשה וקבלת נתיב הורדה

כשיוצרים sdfdownloadtask, מוחזר operation. הפעולה הזו מייצגת את הסטטוס של הפעולה האסינכרונית של יצירת SDF בזמן היצירה. באמצעות ה-method sdfdownloadtasks.operations.get אתם יכולים לבדוק את הפעולה כדי לראות אם היא הסתיימה ומוכנה להורדה, או אם הוצגה הודעת שגיאה.

בסיום הפעולה, הערך בשדה done לא יהיה ריק. הפעולה הסופית תכלול שדה response או שדה error. אם השדה error מכיל אובייקט Status שמכיל קוד שגיאה והודעה, אפשר לראות פרטים על השגיאה שאירעה. אם השדה response מופיע, הוא יכלול אובייקט עם ערך resourceName שמזהה את הקובץ שנוצר להורדה.

הנה דוגמה לאופן שבו בודקים את הבקשה באמצעות השהיה מעריכית:

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