Protokollzwischenspeicher-Nachrichten

Version 14.0.0 der Python-Clientbibliothek wird ein neuer erforderlicher Konfigurationsparameter mit dem Namen use_proto_plus, der angibt, ob die Bibliothek proto-Plus-Nachrichten oder protobuf-Nachrichten. Weitere Informationen zu Informationen zum Festlegen dieses Parameters finden Sie in der Dokumentation zur Konfiguration.

In diesem Abschnitt werden die Auswirkungen auf die Leistung beschrieben, die sich aus der Auswahl der Arten von zu verwenden, lesen und verstehen Sie um eine fundierte Entscheidung zu treffen. Wenn Sie jedoch auf Version 14.0.0 aktualisieren, ohne Änderungen am Code vorzunehmen, können Sie use_proto_plus auf True, um funktionsgefährdende Änderungen an der Benutzeroberfläche zu vermeiden.

Proto-Plus- und protobuf-Nachrichten im Vergleich

In Version 10.0.0 wurde die Python-Clientbibliothek zu einem neuen Codegenerator migriert eine Pipeline, die integrierte proto-plus-Ansatz zur Verbesserung der Ergonomie der protobuf-Nachrichtenoberfläche, da sie sich mehr wie native Python-Objekte. Der Nachteil dieser Verbesserung besteht darin, dass proto-plus und führt zu Leistungseinbußen.

Proto-Plus-Leistung

Einer der Hauptvorteile von proto-plus ist, dass es protobuf Nachrichten und bekannten Typen, um native Python-Typen durch einen Prozess namens type Marshalling.

Das Marshaling findet statt, wenn auf einer Proto-Plus-Nachrichteninstanz auf ein Feld zugegriffen wird. Wenn ein Feld entweder gelesen oder gesetzt wird, z. B. in einem protobuf Definition:

syntax = "proto3";

message Dog {
  string name = 1;
}

Wenn diese Definition in eine proto-Plus-Klasse konvertiert wird, sieht das so aus: wie hier:

import proto

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

Anschließend können Sie die Dog-Klasse initialisieren und wie gewohnt auf das Feld name zugreifen. jedem anderen Python-Objekt:

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

Beim Lesen und Festlegen des Felds name wird der Wert aus einer nativen Python str in string, sodass dass der Wert mit der protobuf-Laufzeit kompatibel ist.

In der Analyse, die wir seit der Veröffentlichung von Version 10.0.0 durchgeführt haben, haben wir festgestellt, dass die für diese Art von Conversions aufgewendete Zeit groß genug ist, Leistungseinbußen, dass es wichtig ist, Nutzenden die Option zur Verwendung von protobuf zu geben. Nachrichten.

Anwendungsfälle für proto-plus- und protobuf-Nachrichten

Anwendungsfälle für Proto Plus-Nachrichten
Proto-Plus bietet im Vergleich zu protobuf-Nachrichten eine Reihe von ergonomischen Verbesserungen, sodass sie ideal zum Schreiben von verwaltbarem, lesbarem Code sind. Da sie die native Python-Objekte sind, sind sie einfacher zu verwenden und zu verstehen.
Anwendungsfälle für Protobuf-Nachrichten
Protobufs für leistungsabhängige Anwendungsfälle verwenden, insbesondere in Apps große Berichte schnell verarbeiten müssen oder bei denen mutate-Anfragen viele Vorgänge ausführen, z. B. mit BatchJobService oder OfflineUserDataJobService

Nachrichtentypen dynamisch ändern

Nachdem Sie den passenden Mitteilungstyp für Ihre App ausgewählt haben, werden Ihnen möglicherweise dass Sie den anderen Typ für einen bestimmten Workflow verwenden müssen. In diesem Fall lässt sich einfach zwischen den beiden Typen wechseln, indem die Dienstprogramme der Clientbibliothek. Mit derselben Nachrichtenklasse Dog wie oben:

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)

Unterschiede in der Protobuf-Nachrichtenoberfläche

Die Proto-Plus-Oberfläche ist in Details. An dieser Stelle möchten wir jedoch Einige wichtige Unterschiede, die sich auf gängige Anwendungsfälle der Google Ads-Kunden Bibliothek.

Byte-Serialisierung

Proto Plus-Nachrichten
serialized = type(campaign).serialize(campaign)
deserialized = type(campaign).deserialize(serialized)
Protokollzwischenspeicher-Nachrichten
serialized = campaign.SerializeToString()
deserialized = campaign.FromString(serialized)

JSON-Serialisierung

Proto Plus-Nachrichten
serialized = type(campaign).to_json(campaign)
deserialized = type(campaign).from_json(serialized)
Protokollzwischenspeicher-Nachrichten
from google.protobuf.json_format import MessageToJson, Parse

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

Feldmasken

Die von api-core wurde für die Verwendung von protobuf entwickelt Message-Instanzen. Wenn Sie also proto-plus-Nachrichten verwenden, konvertieren Sie sie in protobuf. um das Hilfsprogramm zu verwenden:

Proto Plus-Nachrichten
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)
Protokollzwischenspeicher-Nachrichten
from google.api_core.protobuf_helpers import field_mask

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

Enums

Von Proto-Plus-Nachrichten bereitgestellten Enums sind Instanzen der nativen Python- enum-Typ und daher erbt eine Reihe von unkomplizierten Methoden.

Abruf des Enum-Typs

Wenn Sie Enums mit der Methode GoogleAdsClient.get_type abrufen, werden die Nachrichten unterscheiden sich geringfügig, je nachdem, ob Sie proto-plus- oder protobuf-Nachrichten. Beispiel:

Proto Plus-Nachrichten
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
Protokollzwischenspeicher-Nachrichten
val = client.get_type("CampaignStatusEnum").PAUSED

Um das Abrufen von Enums zu vereinfachen, gibt es GoogleAdsClient Instanz mit einer konsistenten Schnittstelle, unabhängig davon, Nachrichtentyp, den Sie verwenden:

val = client.enums.CampaignStatusEnum.PAUSED

Abruf von Enum-Werten

Manchmal ist es hilfreich, den Wert oder die Feld-ID einer bestimmten Aufzählung zu kennen, Beispiel: PAUSED im CampaignStatusEnum entspricht 3:

Proto Plus-Nachrichten
campaign = client.get_type("Campaign")
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# To read the value of campaign status
print(campaign.status.value)
Protokollzwischenspeicher-Nachrichten
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))

Abrufen von Enum-Namen

Manchmal ist es hilfreich, den Namen eines enum-Felds zu kennen. Wenn beispielsweise aus der API lesen können. Vielleicht ist es hilfreich zu wissen, welcher Kampagnenstatus Ganzzahl 3 entspricht:

Proto Plus-Nachrichten
campaign = client.get_type("Campaign")
campaign.status = client.enums.CampaignStatusEnum.PAUSED
# To read the name of campaign status
print(campaign.status.name)
Protokollzwischenspeicher-Nachrichten
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)

Wiederkehrende Felder

Wie im Abschnitt proto-plus Dokumentation, wiederkehrende Felder entsprechen im Allgemeinen typisierten Listen, d. h., sie verhalten sich fast genauso wie list.

An wiederkehrende skalare Felder anfügen

Beim Addieren von Werten zu wiederholten skalaren type-Felder, z. B. string oder int64 haben, ist die Schnittstelle unabhängig von der Nachricht gleich. Typ:

Proto Plus-Nachrichten
ad.final_urls.append("https://www.example.com")
Protokollzwischenspeicher-Nachrichten
ad.final_urls.append("https://www.example.com")

Dies schließt auch alle anderen gängigen list-Methoden ein, z. B. extend:

Proto Plus-Nachrichten
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Protokollzwischenspeicher-Nachrichten
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])

Nachrichtentypen an wiederkehrende Felder anhängen

Wenn das wiederkehrende Feld kein Skalar ist Typ, das Verhalten beim Hinzufügen zu sich wiederholende Felder etwas anders:

Proto Plus-Nachrichten
frequency_cap = client.get_type("FrequencyCapEntry")
frequency_cap.cap = 100
campaign.frequency_caps.append(frequency_cap)
Protokollzwischenspeicher-Nachrichten
# The add method initializes a message and adds it to the repeated field
frequency_cap = campaign.frequency_caps.add()
frequency_cap.cap = 100

Wiederkehrende Felder zuweisen

Sowohl für skalare als auch für nicht skalar wiederholte Felder können Sie Listen dem auf unterschiedliche Weise:

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

Leere Nachrichten

Manchmal ist es hilfreich zu wissen, ob eine Nachrichteninstanz Informationen enthält oder eines der Felder festgelegt ist.

Proto Plus-Nachrichten
# When using proto-plus messages you can simply check the message for
# truthiness.
is_empty = bool(campaign)
is_empty = not campaign
Protokollzwischenspeicher-Nachrichten
is_empty = campaign.ByteSize() == 0

Nachrichtentext

Wir empfehlen sowohl für proto-plus- als auch protobuf-Nachrichten die Verwendung des copy_from Helper-Methode für den GoogleAdsClient:

client.copy_from(campaign, other_campaign)

Leere Nachrichtenfelder

Das Verfahren zum Festlegen leerer Nachrichtenfelder ist unabhängig von den Nachrichtentyp, den Sie verwenden. Sie müssen nur eine leere Nachricht in das Feld kopieren betroffene Website. Weitere Informationen finden Sie im Abschnitt Nachrichtentext sowie im Abschnitt Leere Nachricht. Leitfaden zu Feldern Hier ist ein Beispiel dafür, um ein leeres Nachrichtenfeld festzulegen:

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

Feldnamen, die reservierte Wörter sind

Bei der Verwendung von proto-Plus-Nachrichten werden Feldnamen automatisch mit einem nachgestelltem Unterstrich , wenn der Name auch ein reserviertes Wort in Python ist. Hier ist ein Beispiel für die Arbeit mit einer Asset-Instanz:

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

Die vollständige Liste der Namen ist im gapicen Stil generator. Es kann sein, auch programmatisch.

Installieren Sie zuerst das Modul:

python -m pip install gapic-generator

Führen Sie dann in einer Python-REPL oder einem Python-Skript folgende Schritte aus:

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

Feldpräsenz

Da die Felder in protobuf-Nachrichteninstanzen Standardwerte haben, ist es nicht ist immer intuitiv zu erkennen, ob ein Feld festgelegt wurde oder nicht.

Proto Plus-Nachrichten
# Use the "in" operator.
has_field = "name" in campaign
Protokollzwischenspeicher-Nachrichten
campaign = client.get_type("Campaign")
# Determines whether "name" is set and not just an empty string.
campaign.HasField("name")

Protokollzwischenspeicher Message Klassenschnittstelle über eine HasField-Methode verfügt, die bestimmt, ob das Feld Nachricht festgelegt wurde, auch wenn sie auf einen Standardwert eingestellt war.

Protokollzwischenspeicher-Nachrichtenmethoden

Die protobuf-Nachrichtenschnittstelle enthält einige praktische Methoden, die nicht Teil der proto-Plus-Schnittstelle; Der Zugriff darauf ist jedoch einfach, Konvertieren einer proto-plus-Nachricht in ihr protobuf-Gegenstück:

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

Problemverfolgung

Wenn Sie Fragen zu diesen Änderungen oder Probleme bei der Migration zu Version 14.0.0 der Bibliothek, reichen Sie eine auf unserer Tracker.