באמצעות פרמטר התצורה use_proto_plus
, אפשר לציין אם הספרייה תחזיר הודעות proto-plus או הודעות protobuf. פרטים על הגדרת הפרמטר הזה מופיעים במסמכי ההגדרה.
בקטע הזה מתוארות ההשלכות על הביצועים של בחירת סוגי ההודעות שבהם רוצים להשתמש. לכן מומלץ לקרוא את האפשרויות ולהבין אותן כדי לקבל החלטה מושכלת.
הודעות Proto-plus לעומת הודעות protobuf
צינור עיבוד הנתונים של הקוד המבוסס על ה-generator משלב את proto-plus כדי לשפר את הארגונומיה של ממשק ההודעות של protobuf, כך שהן יתנהגו יותר כמו אובייקטים מקומיים של Python. עם זאת, המשמעות היא שהשימוש ב-proto-plus מגדיל את זמן האחזור של הביצועים.
ביצועים של Proto-plus
אחד מהיתרונות המרכזיים של proto-plus הוא שהוא ממיר הודעות protobuf וסוגי נתונים מוכרים לסוגים מקומיים של Python באמצעות תהליך שנקרא type marshaling.
יצירת המארחים מתרחשת כשמתבצעת גישה לשדה במופע של הודעת 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
ומגדירים אותו, הערך מומר מסוג str
מקורי של Python לסוג string
כדי שהערך יהיה תואם לסביבת זמן הריצה של protobuf.
על סמך ניתוחי הביצועים שלנו, הגענו למסקנה שהזמן שחולף על ביצוע ההמרות מהסוג הזה משפיע על הביצועים בצורה משמעותית, ולכן המשתמשים צריכים להחליט, על סמך הצרכים שלהם, אם להשתמש בהודעות protobuf או לא.
תרחישים לדוגמה להודעות proto-plus ו-protobuf
- תרחישים לדוגמה להעברת הודעות Proto-plus
- Proto-plus מציע מספר שיפורים ארגונומיים בהשוואה להודעות protobuf, ולכן הוא אידיאלי לכתיבה של קוד שקל לקרוא ולתחזק. הם חושפים אובייקטים מקומיים של Python, ולכן קל יותר להשתמש בהם ולהבין אותם.
- תרחישים לדוגמה להעברת הודעות ב-Protobuf
- שימוש ב-protobufs בתרחישי שימוש שרגישים לביצועים, במיוחד באפליקציות שצריכות לעבד דוחות גדולים במהירות, או באפליקציות שמפתחות בקשות לשינוי עם מספר גדול של פעולות, למשל באמצעות
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-plus
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- הודעות Protobuf
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
סריאליזציה של JSON
- הודעות Proto-plus
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-plus
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-plus או protobuf. לדוגמה:
- הודעות Proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- הודעות Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
כדי להקל על אחזור של ערכים מתוך מערכי ערכים, יש מאפיין נוחות במופעים של GoogleAdsClient
שיש לו ממשק עקבי ללא קשר לסוג ההודעה שבה אתם משתמשים:
val = client.enums.CampaignStatusEnum.PAUSED
אחזור ערך של טיפוס בן מנייה (enum)
לפעמים כדאי לדעת את הערך או מזהה השדה של enum נתון. לדוגמה, הערך PAUSED
בשדה CampaignStatusEnum
תואם ל-3
:
- הודעות Proto-plus
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, יכול להיות שתרצו לדעת לאיזה סטטוס קמפיין מתאים המספר המלא 3
:
- הודעות Proto-plus
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
.
הוספת ערכים לשדות סקלריים חוזרים
כשמוסיפים ערכים לשדות חוזרים מסוג scalar, למשל שדות string
או int64
, הממשק זהה ללא קשר לסוג ההודעה:
- הודעות Proto-plus
ad.final_urls.append("https://www.example.com")
- הודעות Protobuf
ad.final_urls.append("https://www.example.com")
האפשרות הזו כוללת גם את כל השיטות הנפוצות האחרות של list
, למשל extend
:
- הודעות Proto-plus
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"])
צירוף סוגי הודעות לשדות חוזרים
אם השדה החוזר הוא לא סקלרי, ההתנהגות בזמן ההוספה שלו לשדות חוזרים שונה במקצת:
- הודעות Proto-plus
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-plus
# 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-plus
# 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, מומלץ להשתמש ב-method העזר של 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
הרשימה המלאה של השמות השמורים נוצרת במודול gapic generator. אפשר לגשת אליו גם באופן פרוגרמטי.
קודם כול, מתקינים את המודול:
python -m pip install gapic-generator
לאחר מכן, בסקריפט או ב-REPL של Python:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
נוכחות בשדה
מכיוון שלשדות במופעים של הודעות protobuf יש ערכי ברירת מחדל, לא תמיד קל לדעת אם שדה הוגדר או לא.
- הודעות Proto-plus
# 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
של protobuf יש שיטה HasField
שמאפשרת לקבוע אם השדה בהודעה הוגדר, גם אם הוא הוגדר לערך ברירת מחדל.
שיטות של הודעות Protobuf
ממשק ההודעות של protobuf כולל כמה שיטות נוחות שלא נכללות בממשק proto-plus. עם זאת, קל לגשת אליהן על ידי המרת הודעה של proto-plus ל-protobuf המקבילה שלה:
# 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())
מעקב אחר בעיות
אם יש לכם שאלות לגבי השינויים האלה או בעיות בהעברה לגרסה האחרונה של הספרייה, אתם יכולים לדווח על הבעיה במערכת המעקב שלנו.