Protobuf মেসেজ

use_proto_plus কনফিগারেশন প্যারামিটারের সাহায্যে, আপনি লাইব্রেরি থেকে proto-plus মেসেজ নাকি protobuf মেসেজ পেতে চান তা নির্দিষ্ট করতে পারবেন। এই প্যারামিটার কীভাবে সেট করবেন সেই সম্পর্কে বিস্তারিত জানতে, কনফিগারেশন ডকুমেন্ট দেখুন।

এই বিভাগে প্রতিটি বিকল্পের পারফর্ম্যান্সের প্রভাব বর্ণনা করা হয়েছে যাতে আপনি আপনার অ্যাপ্লিকেশনের জন্য সেরা পদ্ধতি বেছে নিতে পারেন।

Proto-plus বনাম protobuf মেসেজ

কোড জেনারেটর পাইপলাইন proto-plus ইন্টিগ্রেট করে যাতে protobuf মেসেজ ইন্টারফেসের এরগোনমিক্স উন্নত করা যায়। এর ফলে, এগুলি আরও বেশি স্ট্যান্ডার্ড Python অবজেক্টের মতো কাজ করে। তবে, এর অর্থ হল proto-plus ব্যবহার করলে পারফর্ম্যান্স ওভারহেড হয়।

Proto-plus পারফর্ম্যান্স

proto-plus-এর অন্যতম প্রধান সুবিধা হল, এটি টাইপ মার্শালিং নামক একটি প্রসেসের মাধ্যমে protobuf মেসেজ এবং সুপরিচিত ধরনকে বিল্ট-ইন Python ধরনে কনভার্ট করে।

প্রোটো-প্লাস মেসেজ ইনস্ট্যান্সে কোনও ফিল্ড অ্যাক্সেস করা হলে, বিশেষ করে কোনও ফিল্ড রিড বা সেট করা হলে, মার্শালিং হয়, যেমন, কোনও প্রোটোবাফ সংজ্ঞায়:

syntax = "proto3";

message Dog {
  string name = 1;
}

এই সংজ্ঞাটি যখন একটি প্রোটো-প্লাস ক্লাসে রূপান্তরিত হয়, তখন এটি দেখতে এইরকম হয়:

import proto


class Dog(proto.Message):
    name = proto.Field(proto.STRING, number=1)

আপনি তারপর Dog ক্লাস শুরু করতে পারবেন এবং অন্য যেকোনও Python অবজেক্টের মতো এটির name ফিল্ড অ্যাক্সেস করতে পারবেন:

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 অবজেক্ট এক্সপোজ করে, তাই এগুলি ব্যবহার করা এবং বোঝা সহজ।
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 মেসেজ ইন্টারফেসের পার্থক্য

প্রোটো-প্লাস ইন্টারফেস বিস্তারিতভাবে ডকুমেন্ট করা আছে এবং নিম্নলিখিত বিভাগগুলি Google Ads ক্লায়েন্ট লাইব্রেরির সাধারণ ব্যবহারের ক্ষেত্রে প্রভাব ফেলে এমন মূল পার্থক্যগুলি হাইলাইট করে।

বাইট সিরিয়ালাইজেশন

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 মেসেজ
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)

Enums

প্রোটো-প্লাস মেসেজের মাধ্যমে প্রকাশ করা এনাম হল Python-এর বিল্ট-ইন enum ধরনের ইনস্ট্যান্স এবং তাই এটি অনেক সুবিধাজনক পদ্ধতি ইনহেরিট করে।

Enum টাইপ রিট্রিভাল

enum ফিরিয়ে আনার জন্য GoogleAdsClient.get_type পদ্ধতি ব্যবহার করার সময়, যে মেসেজগুলি ফিরিয়ে আনা হয় সেগুলি আপনি proto-plus নাকি protobuf মেসেজ ব্যবহার করছেন তার উপর নির্ভর করে সামান্য আলাদা হয়। যেমন:

Proto-plus মেসেজ
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
Protobuf মেসেজ
val = client.get_type("CampaignStatusEnum").PAUSED

enum সহজে ফিরিয়ে আনার জন্য, GoogleAdsClient ইনস্ট্যান্সে একটি সুবিধাজনক অ্যাট্রিবিউট আছে যেটির ইন্টারফেস আপনি যে ধরনের মেসেজ ব্যবহার করছেন তার উপর নির্ভর করে না:

val = client.enums.CampaignStatusEnum.PAUSED

Enum ভ্যালু ফিরিয়ে আনা

কখনও কখনও প্রদত্ত 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)
Protobuf মেসেজ
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 ফিল্ডের নাম জানা থাকলে সুবিধা হয়। যেমন, API থেকে অবজেক্ট পড়ার সময় আপনি হয়ত জানতে চাইবেন যে কোন ক্যাম্পেন স্ট্যাটাস 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
print(status_enum.CampaignStatus.Name(campaign.status))

রিপিটেড ফিল্ড

proto-plus docs-এ যেমন বর্ণনা করা হয়েছে, রিপিট করা ফিল্ড সাধারণত টাইপ করা তালিকার সমতুল্য, যার অর্থ হল সেগুলি প্রায় list-এর মতো আচরণ করে।

পুনরাবৃত্ত স্কেলার ফিল্ডে ভ্যালু যোগ করুন

পুনরাবৃত্ত স্কেলার টাইপ ফিল্ডে ভ্যালু যোগ করার সময়, যেমন 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 check the message for truthiness.
is_empty = not bool(campaign)
Protobuf মেসেজ
is_empty = campaign.ByteSize() == 0

মেসেজের কপি

প্রোটো-প্লাস এবং প্রোটোবাফ মেসেজ, দুটির জন্যই copy_from সহায়ক পদ্ধতি ব্যবহার করুন GoogleAdsClient-এ:

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

রিজার্ভ করা নামের সম্পূর্ণ তালিকা 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
Protobuf মেসেজ
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 হয়।)

Protobuf মেসেজ পদ্ধতি

প্রোটোবাফ মেসেজ ইন্টারফেসে কিছু সুবিধাজনক পদ্ধতি অন্তর্ভুক্ত থাকে যা প্রোটো-প্লাস ইন্টারফেসের অংশ নয়; তবে, আপনি একটি প্রোটো-প্লাস মেসেজকে তার প্রোটোবাফ কাউন্টারপার্টে রূপান্তর করে সেগুলি অ্যাক্সেস করতে পারেন:

# 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()

সমস্যার ট্র্যাকার

এইসব পরিবর্তন সম্পর্কে আপনার কোনও প্রশ্ন থাকলে অথবা লাইব্রেরির লেটেস্ট ভার্সনে মাইগ্রেট করার সময় কোনও সমস্যা হলে, ইস্যু ট্র্যাকারে সমস্যা ফাইল করুন।