رسائل Protobuf

الإصدار 14.0.0 من مكتبة برامج بايثون يقدّم معلَمة إعداد جديدة مطلوبة يُسمى use_proto_plus، ويحدد ما إذا كنت تريد عرض المكتبة أم لا رسائل أولية أو رسائل النموذج الأولي للحصول على تفاصيل حول كيفية ضبط هذه المَعلمة، راجِع مستندات الضبط.

يصف هذا القسم آثار الأداء المترتبة على اختيار أنواع التي ينبغي استخدامها، لذا ننصحك بقراءة الخيارات من أجل اتخاذ قرار مستنير. ومع ذلك، إذا كنت تريد الترقية إلى الإصدار 14.0.0 بدون إجراء تغييرات على الرمز، يمكنك ضبط من use_proto_plus إلى True لتجنُّب إيقاف تغييرات الواجهة.

Proto-plus مقابل رسائل Protobuf

في الإصدار 10.0.0، تم نقل مكتبة برامج Python إلى أداة إنشاء رموز جديدة. مسار تكاملي يتكامل proto-plus كوسيلة لتحسين هندسة واجهة رسالة النموذج الأولي من خلال جعلها تتصرف بشكل أكبر مثل كائنات بايثون الأصلية. المقايضة بين هذا التحسين هو أن Protoplus تقدم النفقات العامة للأداء.

أداء Proto-plus

تتمثل إحدى المزايا الأساسية لـ Proto-plus في أنها تقوم بتحويل protobuf الرسائل والأنواع المعروفة أنواع بايثون الأصلية من خلال عملية تسمى type وترتيبه.

تحدث عملية التنظيم عندما يتم الوصول إلى حقل على مثيل الرسالة الأولية، تحديدًا عندما تتم قراءة الحقل أو تعيينه، على سبيل المثال، في نموذج أولي التعريف:

syntax = "proto3";

message Dog {
  string name = 1;
}

عندما يتم تحويل هذا التعريف إلى فئة Proto-plus، سيبدو شيئًا النحو التالي:

import proto

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

يمكنك بعد ذلك إعداد الفئة Dog والوصول إلى الحقل name الخاص بها كما تفعل. أي كائن بايثون آخر:

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

عند قراءة حقل name وإعداده، يتم تحويل القيمة من قيمة من النوع str في Python إلى النوع string وبالتالي أن القيمة متوافقة مع وقت تشغيل Protobuf.

في التحليل الذي أجريناه منذ إطلاق الإصدار 10.0.0، أنّ الوقت المستغرَق في إجراء هذه الأنواع من الإحالات الناجحة كبير بما يكفي تأثير الأداء، من المهم منح المستخدمين خيار استخدام النموذج الأوّلي الرسائل.

حالات الاستخدام الخاصة برسائل Proto-plus وProtobuf

حالات استخدام رسالة Proto-plus
يوفّر Proto-plus عددًا من التحسينات المريحة مقارنةً بالرسائل الأوّلية، لذا فهي مثالية لكتابة التعليمات البرمجية القابلة للصيانة والقابلة للقراءة. نظرًا لأنها تكشف فهو أسهل في الاستخدام والفهم.
حالات استخدام رسالة 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)

الاختلافات في واجهة رسالة النموذج الأوّلي

وقد تم توثيق واجهة Proto-plus في التفاصيل، ولكن سنسلط الضوء هنا على بعض الاختلافات الرئيسية التي تؤثر في حالات الاستخدام الشائعة لعميل "إعلانات Google" المكتبة.

تسلسل وحدات البايت

رسائل Proto-plus
serialized = type(campaign).serialize(campaign)
deserialized = type(campaign).deserialize(serialized)
رسائل النموذج الأولي
serialized = campaign.SerializeToString()
deserialized = campaign.FromString(serialized)

تسلسل JSON

رسائل Proto-plus
serialized = type(campaign).to_json(campaign)
deserialized = type(campaign).from_json(serialized)
رسائل النموذج الأولي
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)
رسائل النموذج الأولي
from google.api_core.protobuf_helpers import field_mask

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

عمليات التعداد

إن التعدادات التي تظهر بواسطة رسائل Proto-plus هي مثيلات للغة بايثون الأصلية النوع enum وبالتالي أن ترث عددًا من طرق الراحة.

استرداد نوع التعداد

عند استخدام طريقة GoogleAdsClient.get_type لاسترداد التعدادات، يتم إرسال الرسائل التي يتم إرجاعها مختلفة قليلاً بناءً على ما إذا كنت تستخدم أو Proto-plus أو Protobuf. على سبيل المثال:

رسائل Proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
رسائل النموذج الأولي
val = client.get_type("CampaignStatusEnum").PAUSED

لتبسيط استرداد التعدادات، توجد سمة ملائمة على GoogleAdsClient مثيلات لها واجهة متسقة بغض النظر عن نوع الرسالة التي تستخدمها:

val = client.enums.CampaignStatusEnum.PAUSED

استرداد قيمة التعداد

قد يكون من المفيد أحيانًا معرفة قيمة، أو معرّف الحقل، لتعداد معين، مثال، يتجاوب 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)
رسائل النموذج الأولي
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))

استرداد اسم التعداد

قد يكون من المفيد أحيانًا معرفة اسم حقل تعداد. على سبيل المثال، عندما قراءة الكائنات من واجهة برمجة التطبيقات قد ترغب في معرفة حالة الحملة 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)
رسائل النموذج الأولي
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"، لا تتغيّر الواجهة بغض النظر عن الرسالة. type:

رسائل Proto-plus
ad.final_urls.append("https://www.example.com")
رسائل النموذج الأولي
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"])
رسائل النموذج الأولي
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)
رسائل النموذج الأولي
# 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 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
رسائل النموذج الأولي
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، تظهر أسماء الحقول تلقائيًا مع شرطة سفلية لاحقة إذا كان الاسم أيضًا كلمة محجوزة في بايثون. إليك مثال على العمل باستخدام مثيل Asset:

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

توضح القائمة الكاملة للحجوزات الأسماء تم إنشاؤها في gapic منشئ المحتوى. يمكن أن تكون يتم الوصول إليها برمجيًا أيضًا.

أولاً، ثبِّت الوحدة:

python -m pip install gapic-generator

ثم في Python REPL أو البرنامج النصي:

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

الحضور الميداني

نظرًا لأن الحقول في مثيلات رسالة النموذج الأولي لها قيم افتراضية، فإنه ليس بديهيًا دائمًا لمعرفة ما إذا كان قد تم تعيين الحقل أم لا.

رسائل Proto-plus
# Use the "in" operator.
has_field = "name" in campaign
رسائل النموذج الأولي
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؛ ومع ذلك، من السهل الوصول إليها عن طريق تحويل رسالة 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 من المكتبة، يُرجى التقدم المشكلة في جديد.