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

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

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

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

कोड जनरेट करने वाली पाइपलाइन, proto-plus को इंटिग्रेट करती है. इससे, protobuf मैसेज इंटरफ़ेस को बेहतर बनाया जा सकता है. ऐसा इसलिए, ताकि वे स्टैंडर्ड Python ऑब्जेक्ट की तरह काम कर सकें. हालांकि, इसका मतलब यह है कि proto-plus का इस्तेमाल करने से परफ़ॉर्मेंस पर असर पड़ता है.

Proto-plus की परफ़ॉर्मेंस

proto-plus का एक मुख्य फ़ायदा यह है कि यह protobuf मैसेज और जाने-माने टाइप को, टाइप मार्शेलिंग नाम की प्रोसेस के ज़रिए, Python के बिल्ट-इन टाइप में बदल देता है.

मार्शलिंग तब होती है, जब किसी फ़ील्ड को 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 फ़ील्ड को ऐक्सेस किया जा सकता है. ऐसा किसी अन्य Python ऑब्जेक्ट की तरह ही किया जा सकता है:

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

name फ़ील्ड को पढ़ते और सेट करते समय, वैल्यू को बिल्ट-इन Python str टाइप से string टाइप में बदल दिया जाता है, ताकि वैल्यू protobuf रनटाइम के साथ काम कर सके.

टाइप कन्वर्ज़न में लगने वाले समय का परफ़ॉर्मेंस पर काफ़ी असर पड़ता है. इसलिए, आपको अपने ऐप्लिकेशन की ज़रूरतों के हिसाब से यह तय करना चाहिए कि proto-plus या protobuf मैसेज का इस्तेमाल करना है या नहीं.

proto-plus और protobuf मैसेज के इस्तेमाल के उदाहरण

Proto-plus मैसेज के इस्तेमाल के उदाहरण
Proto-plus, protobuf मैसेज की तुलना में कई तरह से बेहतर है. इसलिए, यह ऐसे कोड को लिखने के लिए सबसे सही है जिसे आसानी से समझा जा सके और जिसमें बदलाव किया जा सके. ये स्टैंडर्ड 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)

Protobuf मैसेज इंटरफ़ेस में अंतर

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

बाइट क्रम से लगाने की सेटिंग

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)

Enums

proto-plus मैसेज से दिखाए गए enum, Python के बिल्ट-इन enum टाइप के इंस्टेंस होते हैं. इसलिए, इनमें कई सुविधाजनक तरीके शामिल होते हैं.

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

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

कभी-कभी, किसी दिए गए इनम की वैल्यू या फ़ील्ड आईडी जानना फ़ायदेमंद होता है. उदाहरण के लिए, CampaignStatusEnum पर मौजूद PAUSED, 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
# Native protobuf enum fields already store the integer value (3):
print(campaign.status)
# Or look up the integer value from the enum name string:
print(status_enum.CampaignStatus.Value("PAUSED"))

Enum के नाम की जानकारी पाना

कभी-कभी, किसी enum फ़ील्ड का नाम जानना फ़ायदेमंद होता है. उदाहरण के लिए, एपीआई से ऑब्जेक्ट पढ़ते समय, आपको यह जानना पड़ सकता है कि पूर्णांक 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
print(status_enum.CampaignStatus.Name(campaign.status))

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

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

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

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

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 check the message for truthiness.
is_empty = not bool(campaign)
प्रोटोबफ़ मैसेज
is_empty = campaign.ByteSize() == 0

मैसेज की कॉपी

proto-plus और protobuf, दोनों तरह के मैसेज के लिए, GoogleAdsClient पर copy_from हेल्पर तरीके का इस्तेमाल करें:

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

आरक्षित नामों की पूरी सूची, 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")

protobuf Message क्लास इंटरफ़ेस में एक HasField तरीका होता है. इससे यह पता चलता है कि किसी मैसेज पर सब-मैसेज, oneof फ़ील्ड या optional स्केलर फ़ील्ड सेट किया गया है या नहीं. भले ही, उसे डिफ़ॉल्ट वैल्यू पर सेट किया गया हो. (proto3 में मौजूद स्केलर फ़ील्ड के लिए, HasField को कॉल करने पर ValueError जनरेट होता है.)

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

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

# Accessing the ListFields method
protobuf_campaign = util.convert_proto_plus_to_protobuf(campaign)
print(protobuf_campaign.ListFields())

# Accessing the Clear method
protobuf_campaign = util.convert_proto_plus_to_protobuf(campaign)
protobuf_campaign.Clear()

सॉफ़्टवेयर वर्शन ट्रैकर

अगर आपको इन बदलावों के बारे में कोई सवाल पूछना है या लाइब्रेरी के नए वर्शन पर माइग्रेट करने में कोई समस्या आ रही है, तो समस्या ट्रैकर पर समस्या की जानकारी दें.