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

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

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

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

تم توثيق واجهة 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. ويمكن أيضًا الوصول إليه آليًا.

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

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

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

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