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

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

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

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

प्रोटो-प्लस मैसेज के इस्तेमाल के उदाहरण
Proto-plus में, प्रोटोबफ़ मैसेज की तुलना में कई एर्गोनॉमिक सुधार की सुविधा है, ताकि इन्हें आसानी से पढ़ा जा सके और इन्हें आसानी से लिखा जा सके. वे नेटिव 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 टाइप रिट्रीवल

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 पर माइग्रेट करने से जुड़ी समस्याओं के बारे में आपका कोई सवाल है, तो हमारे ट्रैकर पर समस्या दर्ज करें.