प्रोटोबफ़ मैसेज

Python क्लाइंट लाइब्रेरी के वर्शन 14.0.0 में एक नया ज़रूरी कॉन्फ़िगरेशन पैरामीटर जोड़ा गया है, जिसे use_proto_plus कहते हैं. इससे पता चलता है कि लाइब्रेरी को प्रोटो-प्लस मैसेज दिखाने हैं या प्रोटोबफ़ मैसेज में. इस पैरामीटर को सेट करने के तरीके के बारे में ज़्यादा जानने के लिए, कॉन्फ़िगरेशन दस्तावेज़ देखें.

इस सेक्शन में बताया गया है कि किस तरह के मैसेज का इस्तेमाल करना चाहिए. इससे, परफ़ॉर्मेंस पर पड़ने वाले असर के बारे में पता चलता है. इसलिए, हमारा सुझाव है कि आप सोच-समझकर फ़ैसला लेने के लिए, विकल्पों को पढ़ें और समझें. हालांकि, अगर आपको कोड में बदलाव किए बिना, 14.0.0 वर्शन पर अपग्रेड करना है, तो इंटरफ़ेस में किए गए बदलावों से बचने के लिए, use_proto_plus को True पर सेट करें.

प्रोटो-प्लस मैसेज बनाम प्रोटोबफ़ मैसेज

वर्शन 10.0.0 में Python क्लाइंट लाइब्रेरी को एक नई कोड जनरेटर पाइपलाइन पर माइग्रेट किया गया. इसमें प्रोटोबफ़ मैसेज इंटरफ़ेस के एर्गोनॉमिक्स को बेहतर बनाने के लिए, प्रोटो-प्लस को इंटिग्रेट किया गया था. ऐसा करके, ये प्रोटोबफ़ मैसेज के इंटरफ़ेस की एर्गोनॉमिक्स को बेहतर बनाते हैं, ताकि ये नेटिव Python ऑब्जेक्ट की तरह ज़्यादा काम कर सकें. इस सुधार का फ़ायदा यह है कि प्रोटो-प्लस से परफ़ॉर्मेंस का बेहतर डेटा मिलता है.

प्रोटो-प्लस परफ़ॉर्मेंस

प्रोटो-प्लस का एक मुख्य फ़ायदा यह है कि यह टाइप मार्शलिंग नाम की प्रोसेस के ज़रिए प्रोटोबफ़ मैसेज और जाने-पहचाने टाइप को नेटिव 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 टाइप से string टाइप में बदल दिया जाता है, ताकि यह वैल्यू प्रोटोबफ़ रनटाइम के साथ काम कर सके.

वर्शन 10.0.0 की रिलीज़ के बाद से किए गए विश्लेषण में हमने पाया है कि इस तरह के कन्वर्ज़न में लगने वाले समय का परफ़ॉर्मेंस पर इतना असर पड़ा है कि उपयोगकर्ताओं को प्रोटोबफ़ मैसेज का इस्तेमाल करने का विकल्प देना ज़रूरी है.

प्रोटो-प्लस और प्रोटोबफ़ मैसेज के लिए केस इस्तेमाल करें

प्रोटो-प्लस मैसेज के इस्तेमाल के उदाहरण
प्रोटो-प्लस, प्रोटोबफ़ मैसेज की तुलना में कई आसान सुधार करता है. इसलिए, प्रोटो-प्लस, बनाए जा सकने वाले और आसानी से पढ़े जा सकने वाले कोड लिखने के लिए बिलकुल सही होते हैं. ये नेटिव Python ऑब्जेक्ट दिखाते हैं. इसलिए, उन्हें इस्तेमाल करना और समझना आसान होता है.
प्रोटोबफ़ मैसेज के इस्तेमाल के उदाहरण
खास तौर पर, उन ऐप्लिकेशन के लिए प्रोटोबफ़ का इस्तेमाल करें जिन्हें बड़ी संख्या में रिपोर्ट जल्दी प्रोसेस करने की ज़रूरत होती है या जो बहुत ज़्यादा कार्रवाइयों के लिए बदलाव करने के अनुरोध बनाते हैं. उदाहरण के लिए, 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)

प्रोटोबफ़ मैसेज इंटरफ़ेस में अंतर

प्रोटो-प्लस इंटरफ़ेस विवरण में दस्तावेज़ दिया गया है, लेकिन यहां हम कुछ प्रमुख अंतरों के बारे में बताएंगे, जो Google Ads क्लाइंट लाइब्रेरी के सामान्य उपयोग के उदाहरणों को प्रभावित करते हैं.

बाइट सीरियलाइज़ेशन

प्रोटो-प्लस मैसेज
serialized = type(campaign).serialize(campaign)
deserialized = type(campaign).deserialize(serialized)
प्रोटोबफ़ मैसेज
serialized = campaign.SerializeToString()
deserialized = campaign.FromString(serialized)

JSON को क्रम से लगाना

प्रोटो-प्लस मैसेज
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 से दिया गया फ़ील्ड मास्क हेल्पर तरीका, प्रोटोबफ़ मैसेज इंस्टेंस का इस्तेमाल करने के लिए डिज़ाइन किया गया है. इसलिए, प्रोटो-प्लस मैसेज का इस्तेमाल करते समय, हेल्पर का इस्तेमाल करने के लिए उन्हें प्रोटोबफ़ मैसेज में बदलें:

प्रोटो-प्लस मैसेज
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)

Enums

प्रोटो-प्लस मैसेज से दिखाए गए Enum, Python के नेटिव enum टाइप के इंस्टेंस हैं. इसलिए, इसमें कई आसान तरीके मौजूद हैं.

Enum टाइप की रिकवरी

ईनम पाने के लिए GoogleAdsClient.get_type तरीके का इस्तेमाल करते समय, लौटाए जाने वाले मैसेज थोड़े अलग होते हैं. यह इस बात पर निर्भर करता है कि प्रोटो-प्लस मैसेज का इस्तेमाल किया जा रहा है या प्रोटोबफ़ मैसेज का. उदाहरण के लिए:

प्रोटो-प्लस मैसेज
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
प्रोटोबफ़ मैसेज
val = client.get_type("CampaignStatusEnum").PAUSED

ईनम को आसानी से वापस पाने के लिए, GoogleAdsClient इंस्टेंस पर एक सुविधा एट्रिब्यूट दिया गया है. इसका इंटरफ़ेस एक जैसा है, चाहे आप किसी भी तरह के मैसेज का इस्तेमाल कर रहे हों:

val = client.enums.CampaignStatusEnum.PAUSED

Enum वैल्यू वापस पाना

कभी-कभी किसी ईनम की वैल्यू या फ़ील्ड आईडी को जानना मददगार होता है. उदाहरण के लिए, CampaignStatusEnum पर PAUSED, 3 से जुड़ा होता है:

प्रोटो-प्लस मैसेज
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))

Enum नाम की रिकवरी

कभी-कभी ईनम फ़ील्ड का नाम जानना मददगार होता है. उदाहरण के लिए, एपीआई से ऑब्जेक्ट पढ़ते समय, हो सकता है कि आप यह जानना चाहें कि इंटी 3 किस कैंपेन स्थिति से जुड़ी है:

प्रोटो-प्लस मैसेज
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)

दोहराए गए फ़ील्ड

जैसा कि प्रोटो-प्लस दस्तावेज़ों में बताया गया है, दोहराए गए फ़ील्ड आम तौर पर टाइप की गई सूचियों की तरह होते हैं. इसका मतलब है कि वे list की तरह ही काम करते हैं.

दोहराए गए अदिश फ़ील्ड में जोड़ना

दोहराए गए स्केलर टाइप फ़ील्ड, जैसे कि string या int64 फ़ील्ड में वैल्यू जोड़ते समय, इंटरफ़ेस एक जैसा होता है. भले ही, मैसेज का टाइप कुछ भी हो:

प्रोटो-प्लस मैसेज
ad.final_urls.append("https://www.example.com")
प्रोटोबफ़ मैसेज
ad.final_urls.append("https://www.example.com")

इसमें, list के अन्य सभी सामान्य तरीके भी शामिल हैं, जैसे कि extend:

प्रोटो-प्लस मैसेज
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"])

दोहराए गए फ़ील्ड में मैसेज के टाइप जोड़ना

अगर दोहराया गया फ़ील्ड स्केलर टाइप नहीं है, तो उन्हें दोहराए गए फ़ील्ड में जोड़ने पर काम करने का तरीका थोड़ा अलग होता है:

प्रोटो-प्लस मैसेज
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

दोहराए गए फ़ील्ड असाइन करना

अदिश और गैर-स्केलर दोहराए गए फ़ील्ड, दोनों के लिए आप फ़ील्ड में अलग-अलग तरीकों से सूचियां असाइन कर सकते हैं:

प्रोटो-प्लस मैसेज
# 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

खाली मैसेज

कभी-कभी यह जानना मददगार होता है कि किसी मैसेज इंस्टेंस में कोई जानकारी है या नहीं या उसका कोई फ़ील्ड सेट है या नहीं.

प्रोटो-प्लस मैसेज
# 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

मैसेज की कॉपी

हमारा सुझाव है कि प्रोटो-प्लस और प्रोटोबफ़ मैसेज, दोनों के लिए GoogleAdsClient पर copy_from हेल्पर तरीके का इस्तेमाल करें:

client.copy_from(campaign, other_campaign)

खाली मैसेज फ़ील्ड

आप चाहे किसी भी तरह के मैसेज का इस्तेमाल कर रहे हों, खाली मैसेज फ़ील्ड को सेट करने का तरीका एक जैसा ही है. आपको बस संबंधित फ़ील्ड में एक खाली मैसेज कॉपी करना होगा. मैसेज कॉपी सेक्शन और मैसेज फ़ील्ड खाली हैं गाइड देखें. यहां खाली मैसेज फ़ील्ड को सेट करने के तरीके का एक उदाहरण दिया गया है:

client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))

फ़ील्ड के ऐसे नाम जो रिज़र्व किए गए हैं

प्रोटो-प्लस मैसेज का इस्तेमाल करते समय, फ़ील्ड के नाम अपने-आप ही पिछले अंडरस्कोर के साथ दिखते हैं. अगर Python में यह नाम भी पहले से मौजूद शब्द के तौर पर इस्तेमाल होता है. यहां Asset इंस्टेंस के साथ काम करने का एक उदाहरण दिया गया है:

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

रिज़र्व किए गए नामों की पूरी सूची गैपिक जनरेटर मॉड्यूल में बनाई जाती है. इसे प्रोग्राम के हिसाब से ऐक्सेस किया जा सकता है.

सबसे पहले, मॉड्यूल इंस्टॉल करें:

python -m pip install gapic-generator

फिर, Python REPL या स्क्रिप्ट में:

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

फ़ील्ड में मौजूदगी

प्रोटोबफ़ मैसेज इंस्टेंस में मौजूद फ़ील्ड की डिफ़ॉल्ट वैल्यू होती हैं. इसलिए, यह पता करना हमेशा मुश्किल नहीं होता कि फ़ील्ड को सेट किया गया है या नहीं.

प्रोटो-प्लस मैसेज
# 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 तरीका है. इससे यह तय होता है कि मैसेज पर मौजूद फ़ील्ड को सेट किया गया है या नहीं. भले ही, वह डिफ़ॉल्ट वैल्यू पर सेट हो.

प्रोटोबफ़ मैसेज के तरीके

प्रोटोबफ़ मैसेज इंटरफ़ेस में सुविधा के कुछ तरीके शामिल हैं जो प्रोटो-प्लस इंटरफ़ेस का हिस्सा नहीं हैं; हालांकि, एक प्रोटो-प्लस मैसेज को इसके प्रोटोबफ़ मैसेज में बदलकर इन्हें ऐक्सेस करना आसान है:

# 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 पर माइग्रेट करने में कोई समस्या आ रही है, तो हमारे ट्रैकर पर समस्या की शिकायत करें.