Protobuf মেসেজ

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

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

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

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

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

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

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

প্রোটো-প্লাস ইন্টারফেস বিস্তারিতভাবে ডকুমেন্ট করা আছে এবং নিম্নলিখিত বিভাগগুলি 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-এর দেওয়া ফিল্ড মাস্ক হেল্পার পদ্ধতিটি প্রোটোবাফ মেসেজ ইনস্ট্যান্স ব্যবহার করার জন্য ডিজাইন করা হয়েছে। 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)

Enums

proto-plus মেসেজ দ্বারা এক্সপোজ করা এনুম হল 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

এনাম সহজে রিট্রিভ করার জন্য, 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)
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 নাম ফিরিয়ে আনা

কখনও কখনও এনুম ফিল্ডের নাম জানা দরকার হয়। যেমন, 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 ডকুমেন্টে যেভাবে বর্ণনা করা হয়েছে, সেই অনুযায়ী, রিপিট করা ফিল্ডগুলি সাধারণত টাইপ করা তালিকার সমতুল্য, যার অর্থ হল, সেগুলি প্রায় 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

মেসেজের কপি

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)

ফিল্ডের উপস্থিতি

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 মেসেজ পদ্ধতি

protobuf মেসেজ ইন্টারফেসে কিছু কনভেনিয়েন্স পদ্ধতি অন্তর্ভুক্ত থাকে যা proto-plus ইন্টারফেসের অংশ নয়; তবে, আপনি কোনও proto-plus মেসেজকে এর 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()

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

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