הודעות Protobuf

גרסה 14.0.0 מספריית הלקוח של Python כוללת פרמטר הגדרה נדרש חדש. שנקרא use_proto_plus שמציין אם רוצים שהספרייה תחזיר הודעות Proto-Plus או הודעות Protobuf. לפרטים על כדי להגדיר את הפרמטר הזה, קראו את מסמכי ההגדרה.

קטע זה מתאר את ההשלכות על הביצועים של בחירת הסוגים של לכן מומלץ לקרוא ולהבין את האפשרויות השונות כדי לקבל החלטה מושכלת. אבל אם רוצים לשדרג לגרסה 14.0.0 בלי לבצע שינויים בקוד, אפשר להגדיר use_proto_plus עד True כדי למנוע תקלות בממשק.

הודעות Proto-plus לעומת Protobuf

בגרסה 10.0.0 ספריית הלקוח של Python הועברה למחולל קוד חדש שמשולב proto-plus כדרך לשיפור הארגונומית של ממשק המסרים של האב טיפוס באמצעות גרימת התנהגות טובה יותר כמו אובייקטים מקומיים של Python. התוצאה של שיפור זה היא מציג את תקורת הביצועים.

שילוב של Proto-Plus ביצועים

אחד היתרונות העיקריים של פרוטו פלוס הוא שהוא ממיר פרוטובוף הודעות וסוגים ידועים של בשפה נייטיב של Python דרך תהליך שנקרא סוג מארשלינג.

סידור פריטים מתרחש כשניגשים לשדה במכונה של הודעת Proto-plus, במיוחד כשקוראים או מגדירים שדה, לדוגמה, ב-protobuf הגדרה:

syntax = "proto3";

message Dog {
  string name = 1;
}

אם ההגדרה הזו תומר למחלקה מסוג Proto Plus, היא תיראה משהו כך:

import proto

class Dog(proto.Message):
    name = proto.Field(proto.STRING, number=1)

אחרי זה אפשר לאתחל את המחלקה Dog ולגשת לשדה name שלה כמו כל אובייקט Python אחר:

dog = Dog()
dog.name = "Scruffy"
print(dog.name)

כשקוראים ומגדירים את השדה name, הערך מומר ממקור Python str מקלידים string כדי שהערך תואם לסביבת זמן הריצה של ה-protobuf.

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

תרחישים לדוגמה להודעות מסוג Proto-Plus ו-protobuf

תרחישים לדוגמה של שליחת הודעות אל Proto
Proto-plus מציע כמה שיפורים ארגונומיים מאשר הודעות Protobuf, ולכן הן אידיאליות לכתיבת קוד קריא שניתן לתחזוקה. כי הן חושפות קל יותר להשתמש בהם ולהבין אותם.
תרחישים לדוגמה של הודעות Protobuf
שימוש ב-protobuf גרים בתרחישים לדוגמה שרגישים לביצועים, במיוחד באפליקציות שצריכים לעבד דוחות גדולים במהירות, או ליצור בקשות שינוי מספר רב של פעולות, לדוגמה BatchJobService או OfflineUserDataJobService.

שינוי דינמי של סוגי ההודעות

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

from google.ads.googleads import util

# Proto-plus message type
dog = Dog()

# Protobuf message type
dog = util.convert_proto_plus_to_protobuf(dog)

# Back to proto-plus message type
dog = util.convert_protobuf_to_proto_plus(dog)

הבדלים בממשק ההודעות של Protobuf

ממשק Proto Plus מתועד פרט, אבל כאן נדגיש כמה הבדלים מרכזיים שמשפיעים על תרחישים נפוצים לדוגמה בלקוח Google Ads לספרייה.

סריאליזציה של בייטים

הודעות Proto
serialized = type(campaign).serialize(campaign)
deserialized = type(campaign).deserialize(serialized)
הודעות Protobuf
serialized = campaign.SerializeToString()
deserialized = campaign.FromString(serialized)

סריאליזציה ל-JSON

הודעות Proto
serialized = type(campaign).to_json(campaign)
deserialized = type(campaign).from_json(serialized)
הודעות Protobuf
from google.protobuf.json_format import MessageToJson, Parse

serialized = MessageToJson(campaign)
deserialized = Parse(serialized, campaign)

מסכות שדה

שיטת הזיהוי של התממת השדה שסופקה על ידי הקוד api-core נועד להשתמש ב-protobuf מופעים של הודעות. כך שכאשר משתמשים בהודעות מסוג proto-plus, ממירים אותן ל-protobuf הודעות כדי להשתמש בכלי העזר:

הודעות Proto
from google.api_core.protobuf_helpers import field_mask

campaign = client.get_type("Campaign")
protobuf_campaign = util.convert_proto_plus_to_protobuf(campaign)
mask = field_mask(None, protobuf_campaign)
הודעות Protobuf
from google.api_core.protobuf_helpers import field_mask

campaign = client.get_type("Campaign")
mask = field_mask(None, campaign)

טיפוסים בני מנייה (enum)

מספרים שנחשפו באמצעות הודעות Proto Plus הם מופעים של שפת המקור של Python מקלידים enum, ולכן יורשות מספר שיטות נוחות.

אחזור סוג טיפוסים בני מנייה (enum)

כשמשתמשים בשיטה GoogleAdsClient.get_type כדי לאחזר טיפוסים בני מנייה (enum), ההודעות שמוחזרים מעט שונים, בהתאם לשימוש הודעות אב-טיפוס או אב-טיפוס. לדוגמה:

הודעות Proto
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
הודעות Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED

כדי שיהיה קל יותר לאחזר ערכים של טיפוסים בני מנייה (enum), יש מאפיין נוחות מופעל GoogleAdsClient מכונות עם ממשק עקבי, בלי קשר למכונות סוג ההודעה שלך:

val = client.enums.CampaignStatusEnum.PAUSED

אחזור ערך של טיפוסים בני מנייה (enum)

לפעמים כדאי לדעת את הערך, או מזהה השדה, של טיפוסים בני מנייה (enum) נתון, לדוגמה, PAUSED ב-CampaignStatusEnum תואם ל-3:

הודעות Proto
campaign = client.get_type("Campaign")
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# To read the value of campaign status
print(campaign.status.value)
הודעות Protobuf
campaign = client.get_type("Campaign")
status_enum = client.enums.CampaignStatusEnum
campaign.status = status_enum.PAUSED
# To read the value of campaign status
print(status_enum.CampaignStatus.Value(campaign.status))

אחזור שם של טיפוסים בני מנייה (enum)

לפעמים כדאי לדעת את השם של שדה טיפוסים בני מנייה (enum). לדוגמה, כאשר לקרוא אובייקטים מה-API, שאולי תרצו לדעת מה הסטטוס של הקמפיין Int 3 תואם ל:

הודעות Proto
campaign = client.get_type("Campaign")
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# To read the name of campaign status
print(campaign.status.name)
הודעות Protobuf
campaign = client.get_type("Campaign")
status_enum = client.enums.CampaignStatusEnum
# Sets the campaign status to the int value for PAUSED
campaign.status = status_enum.PAUSED
# To read the name of campaign status
status_enum.CampaignStatus.Name(campaign.status)

שדות חוזרים

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

צירוף לשדות סקלריים חוזרים

בעת הוספת ערכים לסקלרר חוזר type. לדוגמה, בשדות string או int64, הממשק זהה ללא קשר להודעה :type

הודעות Proto
ad.final_urls.append("https://www.example.com")
הודעות Protobuf
ad.final_urls.append("https://www.example.com")

זה כולל גם את כל שאר השיטות הנפוצות של list, לדוגמה extend:

הודעות Proto
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
הודעות Protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])

צירוף סוגי הודעות לשדות חוזרים

אם השדה החוזר אינו סקלרי type, את ההתנהגות כשמוסיפים אותם השדות החוזרים שונים מעט:

הודעות Proto
frequency_cap = client.get_type("FrequencyCapEntry")
frequency_cap.cap = 100
campaign.frequency_caps.append(frequency_cap)
הודעות Protobuf
# The add method initializes a message and adds it to the repeated field
frequency_cap = campaign.frequency_caps.add()
frequency_cap.cap = 100

הקצאת שדות חוזרים

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

הודעות Proto
# In proto-plus it's possible to use assignment.
urls = ["https://www.example.com"]
ad.final_urls = urls
הודעות Protobuf
# Protobuf messages do not allow assignment, but you can replace the
# existing list using slice syntax.
urls = ["https://www.example.com"]
ad.final_urls[:] = urls

הודעות ריקות

לפעמים כדאי לדעת אם מופע של הודעה מכיל או אם אחד מהשדות שלו מוגדר.

הודעות Proto
# When using proto-plus messages you can simply check the message for
# truthiness.
is_empty = bool(campaign)
is_empty = not campaign
הודעות Protobuf
is_empty = campaign.ByteSize() == 0

תוכן ההודעה

עבור הודעות מסוג proto Plus ו-protobuf, מומלץ להשתמש בcopy_from שיטת העזרה ב-GoogleAdsClient:

client.copy_from(campaign, other_campaign)

שדות ריקים של הודעות

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

client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))

שמות של שדות שהם מילים שמורות

כשמשתמשים בהודעות מסוג proto-plus, שמות השדות מופיעים באופן אוטומטי עם אם השם הוא גם מילה שמורה ב-Python, יש להוסיף קו תחתון בסוף. הנה דוגמה לעבודה עם מופע של Asset:

asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE

הרשימה המלאה של פריטים שמורים שמות מבוססת על גאפיק של Generative. זה יכול להיות וגם ניגשו באופן פרוגרמטי.

תחילה, מתקינים את המודול:

python -m pip install gapic-generator

לאחר מכן, ב-REPL או בסקריפט של Python:

import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)

נוכחות בשדה

כי לשדות במכונות של הודעות Protobuf יש ערכי ברירת מחדל, תמיד אינטואיטיבית לדעת אם שדה הוגדר או לא.

הודעות Proto
# Use the "in" operator.
has_field = "name" in campaign
הודעות Protobuf
campaign = client.get_type("Campaign")
# Determines whether "name" is set and not just an empty string.
campaign.HasField("name")

הפרוטובוף Message לממשק class יש שיטה HasField שקובעת אם השדה הודעה הוגדרה, גם אם היא הוגדרה לערך ברירת מחדל.

שיטות הודעה ב-Protobuf

ממשק ההודעה של ה-protobuf כולל כמה שיטות נוחות שלא חלק מממשק ה-proto-plus; אבל קל לגשת אליהם בקלות וממירה את הודעת ה-proto-plus להודעה המקבילה שלה:

# Accessing the ListFields method
protobuf_campaign = util.convert_protobuf_to_proto_plus(campaign)
print(campaign.ListFields())

# Accessing the Clear method
protobuf_campaign = util.convert_protobuf_to_proto_plus(campaign)
print(campaign.Clear())

מעקב אחר בעיות

אם יש לך שאלות לגבי השינויים האלה או בעיות כלשהן בהעברה אל גרסה 14.0.0 של הספרייה, צריך להגיש קובץ על הבעיה מכשיר מעקב.