גרסה 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 כדי לשפר את הארגונומיה של ממשק ההודעות של Protobuf ולגרום להם להתנהג יותר כמו אובייקטים מקוריים של Python. היתרון של השיפור הזה הוא שפרוטו פלוס יוצר את תקורת הביצועים.
ביצועים של יתרון מספרי
אחד מהיתרונות המרכזיים של פרוטוקול proto-plus הוא ההמרה של הודעות protobuf וסוגים מוכרים לסוגי Python מקוריים, באמצעות תהליך שנקרא סידור סגנונות.
סידור מתבצע כשניגשים לשדה במופע של הודעת פרוטו פלוס, במיוחד כששדה נקרא או מוגדר, לדוגמה, בהגדרת פרוטובוב:
syntax = "proto3";
message Dog {
string name = 1;
}
כשממירים את ההגדרה הזו למחלקה פרוטו-פלוס, היא תיראה בערך כך:
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
כדי שהערך יתאים לזמן הריצה של הפרוטובופון.
בניתוח שערכנו מאז הפרסום של הגרסה 10.0.0
, הגענו למסקנה שמשך הזמן שנדרש לביצוע המרות מהסוג הזה הוא בעל השפעה גדולה מספיק על הביצועים, וחשוב לתת למשתמשים את האפשרות להשתמש בהודעות protobuf.
תרחישים לדוגמה להודעות proto-plus ו-protobuf
- תרחישים לדוגמה מסוג Proto Plus Messages
- Proto-plus מציע כמה שיפורים ארגונומיים בהשוואה להודעות protobuf, ולכן הן אידיאליות לכתיבת קוד קריא וקריא. מכיוון שהם חושפים אובייקטים מקוריים של Python, קל יותר להשתמש בהם ולהבין אותם.
- תרחישים לדוגמה בהודעת 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
ממשק הפרוטו פלוס מתועד, אבל כאן נדגיש כמה הבדלים עיקריים שמשפיעים על תרחישים נפוצים של שימוש בספריית הלקוח של 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)
טיפוסים בני מנייה (enums)
ערכים שנחשפים על ידי הודעות פרוטו פלוס הם מופעים של סוג enum
המקורי של Python ולכן יורשים כמה שיטות נוחות.
אחזור סוג הטיפוס בן המנייה (enum)
כשמשתמשים בשיטה GoogleAdsClient.get_type
כדי לאחזר טיפוסים בני מנייה (enums), ההודעות שמוחזרות משתנות מעט בהתאם לאופן שבו משתמשים בהודעות פרוטו פלוס או פרוטובוף. למשל:
- הודעות מסוג Proto Plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- הודעות Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
כדי להקל על אחזור מספרי טיפוסים בני מנייה (enum), יש מאפיין נוחות במכונות של GoogleAdsClient
עם ממשק עקבי, בלי קשר לסוג ההודעה שבו משתמשים:
val = client.enums.CampaignStatusEnum.PAUSED
אחזור ערך של טיפוסים בני מנייה (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, כדאי לדעת לאיזה סטטוס קמפיין שייך ה-int 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
.
הוספה לשדות סקלריים חוזרים
כשמוסיפים ערכים לשדות חוזרים של סוג סקלרי, לדוגמה שדות 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
תוכן ההודעה
גם בהודעות פרוטו פלוס וגם בהודעות protobuf, מומלץ להשתמש בשיטת העזרה copy_from
ב-GoogleAdsClient
:
client.copy_from(campaign, other_campaign)
השדות של ההודעה ריקים
התהליך של הגדרת שדות ריקים של הודעות הוא זהה, בלי קשר לסוג ההודעה שבו אתם משתמשים. צריך רק להעתיק הודעה ריקה לשדה הרלוונטי. עיינו בקטע תוכן הודעה וגם במדריך Empty Message Fields (שדות הודעה ריקים). דוגמה להגדרה של שדה הודעה ריק:
client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))
שמות שדות שהם מילים שמורות
כשמשתמשים בהודעות פרוטו פלוס, שמות השדות מופיעים באופן אוטומטי עם קו תחתון בסוף במקרה שהשם הוא גם מילה שמורה ב-Python. דוגמה לעבודה עם מופע של Asset
:
asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE
הרשימה המלאה של השמות השמורים נוצרת במודול gapic. אפשר לגשת אליו גם באופן פרוגרמטי.
קודם כול, מתקינים את המודול:
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
יש שיטה HasField
שקובעת אם השדה בהודעה הוגדר, גם אם הוא הוגדר לערך ברירת מחדל.
שיטות הודעת Protobuf
ממשק ההודעות של protobuf כולל כמה שיטות נוחות שאינן חלק מממשק 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())
מעקב אחר בעיות
אם יש לכם שאלות לגבי השינויים האלה או בעיות במעבר לגרסה 14.0.0
של הספרייה, דווחו על בעיה במכשיר המעקב שלנו.