Versione
14.0.0
della libreria client Python introduce un nuovo parametro di configurazione obbligatorio
denominato use_proto_plus
che specifica se vuoi che la libreria restituisca
messaggi proto-plus oppure
messaggi protobuf. Per maggiori dettagli su
come impostare questo parametro, consulta la documentazione di configurazione.
Questa sezione descrive le implicazioni in termini di rendimento della scelta dei tipi di
messaggi da utilizzare, pertanto, ti consigliamo di leggere e comprendere
le opzioni per poter prendere una decisione consapevole. Tuttavia, se vuoi
eseguire l'upgrade alla versione 14.0.0
senza apportare modifiche al codice, puoi configurare
use_proto_plus
a True
per evitare di interrompere le modifiche all'interfaccia.
Messaggi Proto-plus e protobuf
Nella versione 10.0.0
è stata eseguita la migrazione della libreria client Python a un nuovo generatore di codice
una pipeline che integrava
proto-plus come modo per migliorare
l'ergonomia dell'interfaccia dei messaggi Protobuf, facendoli comportare
come gli oggetti Python nativi. Lo svantaggio di questo miglioramento è che il
che introduce l'overhead delle prestazioni.
Prestazioni proto-plus
Uno dei principali vantaggi di proto-plus è che converte protobuf messaggi e tipi noti per nativi Python attraverso un processo chiamato type marshalling.
Il marshalling si verifica quando si accede a un campo su un'istanza di messaggio proto-plus, in particolare quando un campo viene letto o impostato, ad esempio in un protobuf definizione:
syntax = "proto3";
message Dog {
string name = 1;
}
Quando questa definizione viene convertita in classe proto-plus, viene visualizzata nel seguente modo:
import proto
class Dog(proto.Message):
name = proto.Field(proto.STRING, number=1)
Puoi quindi inizializzare il corso Dog
e accedere al relativo campo name
come faresti
qualsiasi altro oggetto Python:
dog = Dog()
dog.name = "Scruffy"
print(dog.name)
Durante la lettura e l'impostazione del campo name
, il valore viene convertito da un
str
Python a un tipo string
in modo che
che il valore sia compatibile con il runtime protobuf.
Nell'analisi che abbiamo condotto dal rilascio della versione 10.0.0
, abbiamo
determinato che il tempo impiegato per realizzare questo tipo di conversioni
ha un numero di conversioni sufficiente
l'impatto sulle prestazioni ed è importante offrire agli utenti la possibilità di usare protobuf
messaggi.
Casi d'uso per messaggi proto-plus e protobuf
- Casi d'uso dei messaggi proto-plus
- Proto-plus offre una serie di miglioramenti ergonomici rispetto ai messaggi protobuf, quindi sono ideali per scrivere codice gestibile e leggibile. Poiché espongono oggetti Python nativi, sono più facili da usare e da capire.
- Casi d'uso dei messaggi Protobuf
- Usa protobuf per casi d'uso sensibili alle prestazioni, in particolare nelle app
che devono elaborare rapidamente report di grandi dimensioni o che creano richieste di modifica con
un numero elevato di operazioni, ad esempio con
BatchJobService
oppureOfflineUserDataJobService
.
Modifica dinamica dei tipi di messaggi
Dopo aver selezionato il tipo di messaggio appropriato per la tua app, potresti visualizzare
che è necessario utilizzare l'altro tipo per un flusso di lavoro specifico. In questo caso
è facile passare da un tipo all'altro in modo dinamico utilizzando le utilità offerte
libreria client. Utilizzare la stessa classe di messaggi Dog
di cui sopra:
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)
Differenze nell'interfaccia dei messaggi Protobuf
L'interfaccia proto-plus è documentata in dettaglio, ma qui evidenzieremo alcune differenze fondamentali che interessano i casi d'uso più comuni per il cliente Google Ads libreria.
Serializzazione in byte
- Messaggi protocollo più
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- Messaggi Protobuf
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
Serializzazione JSON
- Messaggi protocollo più
serialized = type(campaign).to_json(campaign) deserialized = type(campaign).from_json(serialized)
- Messaggi Protobuf
from google.protobuf.json_format import MessageToJson, Parse serialized = MessageToJson(campaign) deserialized = Parse(serialized, campaign)
Maschere dei campi
Il metodo helper maschera di campo fornito api-core è progettato per utilizzare protobuf di Compute Engine. Quindi, quando utilizzi messaggi proto-plus, convertili in protobuf per utilizzare l'helper:
- Messaggi protocollo più
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)
- Messaggi Protobuf
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") mask = field_mask(None, campaign)
Enum
Le enum esposte dai messaggi proto-plus sono istanze del linguaggio nativo di Python
enum
e quindi
ereditare vari metodi di convenienza.
Recupero tipo enum
Quando utilizzi il metodo GoogleAdsClient.get_type
per recuperare le enumerazioni, i messaggi
restituiti sono leggermente diversi a seconda che tu stia utilizzando
messaggi proto-plus o protobuf. Ad esempio:
- Messaggi protocollo più
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- Messaggi Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
Per semplificare il recupero delle enum, è presente un attributo di convenienza
GoogleAdsClient
istanze con un'interfaccia coerente, indipendentemente da quale
tipo di messaggio in uso:
val = client.enums.CampaignStatusEnum.PAUSED
Recupero valore enum
A volte è utile conoscere il valore, o l'ID campo, di una determinata enum, per
Ad esempio, PAUSED
su CampaignStatusEnum
corrisponde a 3
:
- Messaggi protocollo più
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the value of campaign status print(campaign.status.value)
- Messaggi 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))
Recupero nome enum
A volte è utile conoscere il nome di un campo enum. Ad esempio, quando
e leggere oggetti dall'API, potresti voler sapere quale stato
l'int 3
corrisponde a:
- Messaggi protocollo più
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the name of campaign status print(campaign.status.name)
- Messaggi 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)
Campi ripetuti
Come descritto nella documentazione proto-plus
non web,
i campi ripetuti sono generalmente equivalenti agli elenchi digitati, il che significa che
si comportano quasi allo stesso modo di un list
.
Aggiunta ai campi scalari ripetuti
Quando si aggiungono valori a valori scalari ripetuti
tipo, ad esempio
string
o int64
, l'interfaccia è la stessa indipendentemente dal messaggio
tipo:
- Messaggi protocollo più
ad.final_urls.append("https://www.example.com")
- Messaggi Protobuf
ad.final_urls.append("https://www.example.com")
Sono inclusi anche tutti gli altri metodi list
comuni, ad esempio extend
:
- Messaggi protocollo più
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
- Messaggi Protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Aggiunta di tipi di messaggi ai campi ripetuti
Se il campo ripetuto non è un tipo, il comportamento quando li si aggiunge I campi ripetuti sono leggermente diversi:
- Messaggi protocollo più
frequency_cap = client.get_type("FrequencyCapEntry") frequency_cap.cap = 100 campaign.frequency_caps.append(frequency_cap)
- Messaggi Protobuf
# The add method initializes a message and adds it to the repeated field frequency_cap = campaign.frequency_caps.add() frequency_cap.cap = 100
Assegnare campi ripetuti
Per i campi ripetuti sia scalari che non scalabili, puoi assegnare elenchi campo in diversi modi:
- Messaggi protocollo più
# In proto-plus it's possible to use assignment. urls = ["https://www.example.com"] ad.final_urls = urls
- Messaggi 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
Messaggi vuoti
A volte è utile sapere se un'istanza di messaggio contiene informazioni o ha impostato uno qualsiasi dei suoi campi.
- Messaggi protocollo più
# When using proto-plus messages you can simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not campaign
- Messaggi Protobuf
is_empty = campaign.ByteSize() == 0
Copia del messaggio
Per entrambi i messaggi proto-plus e protobuf, consigliamo di utilizzare l'copy_from
helper in GoogleAdsClient
:
client.copy_from(campaign, other_campaign)
Campi del messaggio vuoti
La procedura per impostare i campi dei messaggi vuoti è la stessa indipendentemente dal tipo di messaggio in uso. Devi solo copiare un messaggio vuoto nel campo in questione. Consulta la sezione Copia del messaggio e la sezione Messaggio vuoto Guida ai campi. Ecco un esempio di come per impostare un campo messaggio vuoto:
client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))
Nomi dei campi che sono parole riservate
Quando utilizzi messaggi Proto+, i nomi dei campi vengono automaticamente visualizzati con un
il trattino basso finale se il nome è anche una parola riservata in Python. Ecco un
esempio di utilizzo di un'istanza Asset
:
asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE
L'elenco completo delle nomi è costruito nel gapic generatore. È possibile a cui si accede in modo programmatico.
Innanzitutto, installa il modulo:
python -m pip install gapic-generator
Quindi, in un REPL o uno script Python:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
Presenza sul campo
Poiché i campi delle istanze di messaggio protobuf hanno valori predefiniti, non Sapere se un campo è stato impostato o meno.
- Messaggi protocollo più
# Use the "in" operator. has_field = "name" in campaign
- Messaggi Protobuf
campaign = client.get_type("Campaign") # Determines whether "name" is set and not just an empty string. campaign.HasField("name")
Il protobuf
Message
class ha un metodo HasField
che determina se il campo in una
anche se è stato impostato su un valore predefinito.
Metodi dei messaggi Protobuf
L'interfaccia dei messaggi protobuf include alcuni metodi di convenienza che non sono dell'interfaccia Proto+, ma è facile accedervi Conversione di un messaggio protobuf nella rispettiva controparte protobuf:
# 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())
Monitoraggio problemi
Se hai domande su queste modifiche o problemi con la migrazione a
versione 14.0.0
della libreria, invia un file
sul nostro
tracker.