رسائل Protobuf

باستخدام مَعلمة الإعداد use_proto_plus، يمكنك تحديد ما إذا كنت تريد أن تعرض المكتبة رسائل Proto-plus أو رسائل Protobuf. ولمعرفة تفاصيل عن كيفية ضبط هذه المَعلمة، يُرجى الاطّلاع على مستندات الضبط.

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

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

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

أداء Proto-plus

من المزايا الأساسية لواجهة برمجة التطبيقات proto-plus هي أنّها تحوّل رسائل protobuf والأنواع المعروفة إلى أنواع Python الأصلية من خلال عملية تُعرف باسم 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 كما تفعل مع أي عنصر آخر في بايثون:

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

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

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

حالات استخدام رسائل proto-plus وprotobuf

حالات استخدام رسائل Proto-plus
يوفّر 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" .

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

رسائل 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)

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

إنّ قوائم القيم المحدّدة التي تعرضها رسائل proto-plus هي نُسخ من نوع enum الأصلي في Python، وبالتالي، فإنه يتم اكتساب عدد من طرق تسهيل الاستخدام.

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

عند استخدام طريقة GoogleAdsClient.get_type لاسترداد القوائم المحددة، تختلف الرسائل التي يتم عرضها قليلاً حسب ما إذا كنت تستخدم رسائل 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

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

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

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

في بعض الأحيان، يكون من المفيد معرفة اسم حقل التعداد. على سبيل المثال، عند قراءة العناصر من واجهة برمجة التطبيقات، قد تريد معرفة حالة الحملة التي تتوافق معها القيمة الكاملة 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 type المتكرّرة، مثل حقول 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، ننصحك باستخدام طريقة المساعدة 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

يتم إنشاء القائمة الكاملة للأسماء المخصّصة في وحدة أداة إنشاء ملف تعريف العميل في Google API (gapic). يمكن الوصول إليها برمجيًا أيضًا.

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

python -m pip install gapic-generator

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

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

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

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

رسائل 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")

تحتوي واجهة فئة protobuf 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())

أداة تتبّع المشاكل

إذا كانت لديك أي أسئلة حول هذه التغييرات أو أي مشاكل في نقل البيانات إلى أحدث إصدار من المكتبة، يُرجى تسجيل مشكلة في نظام التتبّع.