Pesan Protobuf

Versi 14.0.0 library klien Python memperkenalkan parameter konfigurasi baru yang diperlukan bernama use_proto_plus yang menentukan apakah Anda ingin library ditampilkan pesan proto-plus atau pesan protobuf. Untuk mengetahui detail tentang Untuk mengetahui cara menyetel parameter ini, lihat dokumen konfigurasi.

Bagian ini menjelaskan implikasi kinerja memilih jenis untuk digunakan, oleh karena itu, kami menyarankan Anda membaca dan memahami pilihan untuk membuat keputusan yang tepat. Namun, jika Anda ingin mengupgrade ke versi 14.0.0 tanpa mengubah kode, Anda dapat menyiapkan use_proto_plus ke True untuk menghindari gangguan perubahan antarmuka.

Pesan proto-plus versus protobuf

Di versi 10.0.0, library klien Python dimigrasikan ke generator kode baru pipeline yang mengintegrasikan proto-plus sebagai cara untuk meningkatkan ergonomi antarmuka pesan protobuf dengan membuatnya berperilaku lebih seperti objek Python asli. Konsekuensi dari peningkatan ini adalah bahwa proto-plus menyebabkan adanya overhead performa.

Performa proto-plus

Salah satu manfaat inti proto-plus adalah mengonversi protobuf pesan dan jenis yang dikenal luas jenis Python native melalui proses yang disebut jenis marshaling.

Marshaling terjadi saat kolom diakses di instance pesan proto-plus, khususnya ketika kolom dibaca atau disetel, misalnya, dalam protobuf definisi:

syntax = "proto3";

message Dog {
  string name = 1;
}

Jika definisi ini dikonversi ke kelas proto-plus, definisinya akan terlihat seperti seperti ini:

import proto

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

Anda kemudian dapat melakukan inisialisasi class Dog dan mengakses kolom name seperti yang Anda lakukan objek Python lainnya:

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

Saat membaca dan menetapkan kolom name, nilai dikonversi dari native Python str ketik ke jenis string sehingga bahwa nilainya kompatibel dengan runtime protobuf.

Dalam analisis yang telah kita lakukan sejak rilis versi 10.0.0, kita telah menentukan bahwa waktu yang dihabiskan untuk melakukan konversi jenis ini memiliki dampak performa, sehingga penting untuk memberi pengguna opsi untuk menggunakan protobuf membuat pesan teks.

Kasus penggunaan untuk pesan proto-plus dan protobuf

Kasus penggunaan pesan proto-plus
Proto-plus menawarkan sejumlah peningkatan ergonomis dibandingkan pesan protobuf, sehingga cocok untuk menulis kode yang mudah dipelihara dan dibaca. Karena metode tersebut mengekspos objek Python native, mereka lebih mudah digunakan dan dipahami.
Kasus penggunaan pesan Protobuf
Gunakan protobuf untuk kasus penggunaan yang sensitif terhadap performa, khususnya dalam aplikasi yang perlu memproses laporan besar dengan cepat, atau yang membuat permintaan mutasi dengan untuk melakukan operasi dalam jumlah besar, BatchJobService atau OfflineUserDataJobService.

Mengubah jenis pesan secara dinamis

Setelah memilih jenis pesan yang sesuai untuk aplikasi, Anda mungkin menemukan Anda perlu menggunakan jenis lain untuk alur kerja tertentu. Dalam hal ini, mudah beralih di antara dua jenis tersebut secara dinamis menggunakan utilitas yang ditawarkan oleh library klien. Menggunakan class pesan Dog yang sama di atas:

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)

Perbedaan antarmuka pesan Protobuf

Antarmuka proto-plus didokumentasikan dalam , tetapi di sini kita akan menyoroti beberapa perbedaan utama yang memengaruhi kasus penggunaan umum untuk klien Google Ads library.

Serialisasi byte

Pesan {i>proto-plus<i}
serialized = type(campaign).serialize(campaign)
deserialized = type(campaign).deserialize(serialized)
Pesan protobuf
serialized = campaign.SerializeToString()
deserialized = campaign.FromString(serialized)

Serialisasi JSON

Pesan {i>proto-plus<i}
serialized = type(campaign).to_json(campaign)
deserialized = type(campaign).from_json(serialized)
Pesan protobuf
from google.protobuf.json_format import MessageToJson, Parse

serialized = MessageToJson(campaign)
deserialized = Parse(serialized, campaign)

Mask kolom

Metode helper field mask yang disediakan oleh api-core dirancang untuk menggunakan protobuf setiap instance pesan. Jadi, saat menggunakan pesan proto-plus, konversikan pesan tersebut menjadi protobuf pesan untuk memanfaatkan helper:

Pesan {i>proto-plus<i}
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)
Pesan protobuf
from google.api_core.protobuf_helpers import field_mask

campaign = client.get_type("Campaign")
mask = field_mask(None, campaign)

Enum

Enum yang diekspos oleh pesan proto-plus adalah instance Jenis enum, sehingga mewarisi sejumlah metode praktis.

Pengambilan jenis enum

Saat menggunakan metode GoogleAdsClient.get_type untuk mengambil enum, pesan yang dikembalikan sedikit berbeda tergantung pada apakah Anda menggunakan pesan proto-plus atau protobuf. Contoh:

Pesan {i>proto-plus<i}
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
Pesan protobuf
val = client.get_type("CampaignStatusEnum").PAUSED

Untuk menyederhanakan pengambilan enum, ada atribut kemudahan di Instance GoogleAdsClient yang memiliki antarmuka konsisten, terlepas dari jenis pesan yang Anda gunakan:

val = client.enums.CampaignStatusEnum.PAUSED

Pengambilan nilai enum

Terkadang berguna untuk mengetahui nilai, atau ID {i>field<i}, dari enum tertentu, untuk contoh, PAUSED pada CampaignStatusEnum sesuai dengan 3:

Pesan {i>proto-plus<i}
campaign = client.get_type("Campaign")
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# To read the value of campaign status
print(campaign.status.value)
Pesan protobuf
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))

Pengambilan nama enum

Terkadang berguna untuk mengetahui nama kolom enum. Misalnya, ketika membaca objek dari API, Anda mungkin ingin tahu status kampanye mana int 3 sesuai dengan:

Pesan {i>proto-plus<i}
campaign = client.get_type("Campaign")
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# To read the name of campaign status
print(campaign.status.name)
Pesan 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
status_enum.CampaignStatus.Name(campaign.status)

Kolom berulang

Seperti yang dijelaskan dalam proto-plus dokumen, {i>field <i}yang berulang umumnya setara dengan daftar yang diketik, yang berarti bahwa mereka berperilaku hampir sama dengan list.

Menambahkan ke bidang skalar berulang

Saat menambahkan nilai ke skalar berulang type Anda, misalnya Kolom string atau int64, antarmukanya sama, apa pun pesannya jenis:

Pesan {i>proto-plus<i}
ad.final_urls.append("https://www.example.com")
Pesan protobuf
ad.final_urls.append("https://www.example.com")

Hal ini juga mencakup semua metode list umum lainnya, misalnya extend:

Pesan {i>proto-plus<i}
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Pesan protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])

Menambahkan jenis pesan ke kolom berulang

Jika bidang berulang bukan skalar jenis, perilaku saat menambahkannya ke bidang berulang sedikit berbeda:

Pesan {i>proto-plus<i}
frequency_cap = client.get_type("FrequencyCapEntry")
frequency_cap.cap = 100
campaign.frequency_caps.append(frequency_cap)
Pesan protobuf
# The add method initializes a message and adds it to the repeated field
frequency_cap = campaign.frequency_caps.add()
frequency_cap.cap = 100

Menetapkan kolom berulang

Untuk bidang berulang skalar dan non-skalar, Anda dapat menetapkan daftar ke kolom dengan cara yang berbeda:

Pesan {i>proto-plus<i}
# In proto-plus it's possible to use assignment.
urls = ["https://www.example.com"]
ad.final_urls = urls
Pesan 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

Pesan kosong

Terkadang berguna untuk mengetahui apakah instance pesan berisi informasi, atau memiliki salah satu kolomnya.

Pesan {i>proto-plus<i}
# When using proto-plus messages you can simply check the message for
# truthiness.
is_empty = bool(campaign)
is_empty = not campaign
Pesan protobuf
is_empty = campaign.ByteSize() == 0

Salinan pesan

Untuk pesan proto-plus dan protobuf, sebaiknya gunakan atribut copy_from helper pada GoogleAdsClient:

client.copy_from(campaign, other_campaign)

Kolom pesan kosong

Proses untuk menyetel kolom pesan kosong adalah sama, terlepas dari jenis pesan yang Anda gunakan. Anda hanya perlu menyalin pesan kosong ke kolom yang dimaksud. Lihat bagian Salinan pesan serta Pesan Kosong Panduan kolom. Berikut adalah contoh untuk menyetel kolom pesan kosong:

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

Nama kolom yang merupakan kata yang dicadangkan

Saat menggunakan pesan proto-plus, nama kolom secara otomatis muncul dengan garis bawah jika nama juga merupakan kata yang dicadangkan di Python. Berikut adalah contoh penggunaan instance Asset:

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

Daftar lengkap reservasi nama dibangun di area cemerlang generator. Bisa diakses secara terprogram.

Pertama, instal modul:

python -m pip install gapic-generator

Kemudian, dalam REPL atau skrip Python:

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

Keberadaan kolom

Karena kolom pada instance pesan protobuf memiliki nilai default, selalu intuitif untuk mengetahui apakah suatu isian telah ditetapkan atau belum.

Pesan {i>proto-plus<i}
# Use the "in" operator.
has_field = "name" in campaign
Pesan protobuf
campaign = client.get_type("Campaign")
# Determines whether "name" is set and not just an empty string.
campaign.HasField("name")

Protobuf Message memiliki metode HasField yang menentukan apakah kolom pada telah disetel, meskipun disetel ke nilai default.

Metode pesan Protobuf

Antarmuka pesan protobuf menyertakan beberapa metode praktis yang tidak bagian dari antarmuka proto-plus; Namun, mudah untuk mengaksesnya dengan mengonversi pesan proto-plus ke pasangan protobufnya:

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

Issue Tracker

Jika Anda memiliki pertanyaan tentang perubahan ini atau masalah saat bermigrasi ke versi 14.0.0 dari library, ajukan masalah di pelacak.