Versión
14.0.0
de la biblioteca cliente de Python presenta un nuevo parámetro de configuración obligatorio
llamado use_proto_plus
, que especifica si deseas que la biblioteca devuelva
mensajes proto-plus o
mensajes protobuf. Para obtener detalles
para configurar este parámetro, consulta los documentos de configuración.
En esta sección, se describen las implicaciones de rendimiento que tiene elegir los tipos de
mensajes usar, por lo tanto, te recomendamos que leas y comprendas
las opciones para tomar
una decisión informada. Sin embargo, si quieres
actualizar a la versión 14.0.0
sin hacer cambios en el código, puedes configurar
use_proto_plus
a True
para evitar cambios rotundos en la interfaz.
Diferencias entre mensajes proto+ y protobuf
En la versión 10.0.0
, la biblioteca cliente de Python migró a un nuevo generador de código
canalización que integró
proto-plus como una forma de mejorar
la ergonomía de la interfaz de mensajes protobuf, ya que hace que se comporten más
como objetos nativos de Python. La compensación de esta mejora es que proto-plus
presenta una sobrecarga de rendimiento.
Rendimiento de proto+
Uno de los principales beneficios de proto-plus es que convierte protobuf mensajes y los tipos bien conocidos para tipos nativos de Python a través de un proceso llamado type, el ordenamiento.
El ordenamiento se produce cuando se accede a un campo en una instancia de mensaje proto-plus. específicamente, cuando un campo se lee o establece, por ejemplo, en un protobuf definición:
syntax = "proto3";
message Dog {
string name = 1;
}
Cuando esta definición se convierta en una clase proto-plus, se vería algo así. así:
import proto
class Dog(proto.Message):
name = proto.Field(proto.STRING, number=1)
Luego, puedes inicializar la clase Dog
y acceder a su campo name
como lo harías.
cualquier otro objeto de Python:
dog = Dog()
dog.name = "Scruffy"
print(dog.name)
Cuando se lee y se configura el campo name
, el valor se convierte de un nativo
str
de Python a un tipo string
, de modo que
que el valor sea compatible con el entorno de ejecución de protobuf.
En el análisis que realizamos desde el lanzamiento de la versión 10.0.0
,
determinó que el tiempo dedicado a generar este tipo de conversiones corresponde a un
impacto en el rendimiento, es importante darles a los usuarios la opción de usar protobuf
mensajes nuevos.
Casos de uso para mensajes proto-plus y protobuf
- Casos de uso de proto-plus de mensajes
- Proto-plus ofrece varias mejoras ergonómicas en comparación con los mensajes protobuf, por lo que son ideales para escribir código legible y mantenible. Dado que exponen objetos nativos de Python, son más fáciles de usar y comprender.
- Casos de uso de mensajes de protobuf
- Usa protobufs para casos de uso sensibles al rendimiento, específicamente en apps
que necesiten procesar informes grandes rápidamente o que compilen solicitudes de mutación con una
gran cantidad de operaciones, por ejemplo, con
BatchJobService
oOfflineUserDataJobService
Tipos de mensajes que cambian de forma dinámica
Después de seleccionar el tipo de mensaje adecuado para tu app, es posible que encuentres lo siguiente:
que necesitas usar el otro tipo
para un flujo de trabajo específico. En este caso, es
puede cambiar de forma dinámica entre los dos tipos mediante las utilidades que ofrece la
biblioteca cliente. Usa la misma clase de mensaje Dog
anterior:
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)
Diferencias en la interfaz de mensajes de protobuf
La interfaz proto-plus está documentada en detalle, pero aquí destacaremos algunas diferencias clave que afectan los casos de uso comunes para el cliente de Google Ads biblioteca.
Serialización de bytes
- Mensajes proto-plus
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- Mensajes de protobuf
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
Serialización JSON
- Mensajes proto-plus
serialized = type(campaign).to_json(campaign) deserialized = type(campaign).from_json(serialized)
- Mensajes de protobuf
from google.protobuf.json_format import MessageToJson, Parse serialized = MessageToJson(campaign) deserialized = Parse(serialized, campaign)
Máscaras de campo
El método auxiliar de máscara de campo proporcionado por api-core está diseñado para usar protobuf. las instancias de mensajes nuevos. Por lo tanto, cuando uses mensajes proto-plus, conviértelos a protobuf. para utilizar el asistente:
- Mensajes 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)
- Mensajes de protobuf
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") mask = field_mask(None, campaign)
Enumeraciones
Las enumeraciones expuestas por mensajes proto-plus son instancias del lenguaje
enum
y, por lo tanto,
heredarán varios métodos de conveniencia.
Recuperación de tipos de enumeraciones
Cuando usas el método GoogleAdsClient.get_type
para recuperar enumeraciones, los mensajes
que se devuelven son algo diferentes en función de si usas
mensajes proto-plus o protobuf. Por ejemplo:
- Mensajes proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- Mensajes de protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
Para facilitar la recuperación de enumeraciones, hay un atributo de conveniencia en
Instancias GoogleAdsClient
que tienen una interfaz coherente, sin importar la
tipo de mensaje que utilizas:
val = client.enums.CampaignStatusEnum.PAUSED
Recuperación de valores de enumeración
A veces, es útil saber el valor, o ID de campo, de una enumeración determinada, por
Por ejemplo, PAUSED
en CampaignStatusEnum
corresponde a 3
:
- Mensajes proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the value of campaign status print(campaign.status.value)
- Mensajes de 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))
Recuperación de nombres de enumeraciones
A veces, es útil saber el nombre de un campo enum. Por ejemplo, cuando
leer objetos de la API, es posible que desees saber en qué estado de campaña
int 3
corresponde a:
- Mensajes proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the name of campaign status print(campaign.status.name)
- Mensajes de 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)
Campos repetidos
Como se describe en el módulo proto-plus
documentos,
los campos repetidos son generalmente equivalentes a las listas escritas, lo que significa que
se comportan casi de forma idéntica a una list
.
Cómo adjuntar campos escalares repetidos
Cuando se agregan valores a textos escalares repetidos
type, por ejemplo,
string
o int64
, la interfaz es la misma independientemente del mensaje
Tipo:
- Mensajes proto-plus
ad.final_urls.append("https://www.example.com")
- Mensajes de protobuf
ad.final_urls.append("https://www.example.com")
Esto también incluye todos los demás métodos list
comunes, por ejemplo, extend
:
- Mensajes proto-plus
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
- Mensajes de protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Adjunta tipos de mensajes a campos repetidos
Si el campo repetido no es un escalar del tipo de archivo, el comportamiento al momento de agregarlos los campos repetidos es un poco diferente:
- Mensajes proto-plus
frequency_cap = client.get_type("FrequencyCapEntry") frequency_cap.cap = 100 campaign.frequency_caps.append(frequency_cap)
- Mensajes de protobuf
# The add method initializes a message and adds it to the repeated field frequency_cap = campaign.frequency_caps.add() frequency_cap.cap = 100
Asigna campos repetidos
Para campos repetidos escalares y no escalares, puedes asignar listas al de diferentes maneras:
- Mensajes proto-plus
# In proto-plus it's possible to use assignment. urls = ["https://www.example.com"] ad.final_urls = urls
- Mensajes de 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
Mensajes vacíos
A veces, es útil saber si una instancia de mensaje contiene información o que tenga configurado alguno de sus campos.
- Mensajes proto-plus
# When using proto-plus messages you can simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not campaign
- Mensajes de protobuf
is_empty = campaign.ByteSize() == 0
Texto del mensaje
Para los mensajes proto-plus y protobuf, recomendamos usar copy_from
.
método auxiliar en GoogleAdsClient
:
client.copy_from(campaign, other_campaign)
Campos de mensaje vacíos
El proceso para configurar campos de mensaje vacíos es el mismo, independientemente de la el tipo de mensaje que usas. Solo tienes que copiar un mensaje vacío en el campo en cuestión. Consulta la sección Copia de mensaje, así como la sección Mensaje vacío Campos. Aquí hay un ejemplo de cómo Para configurar un campo de mensaje vacío, sigue estos pasos:
client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))
Nombres de campos que son palabras reservadas
Cuando se usan mensajes proto-plus, los nombres de los campos aparecen automáticamente con un
guion bajo final si el nombre también es una palabra reservada en Python. Este es un
Ejemplo de trabajo con una instancia Asset
:
asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE
En la lista completa de anuncios nombres se construye en el gapic generator. Sí, es posible y a los que se puede acceder de forma programática.
Primero, instala el módulo:
python -m pip install gapic-generator
Luego, haz lo siguiente en una REPL o secuencia de comandos de Python:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
Presencia en el campo
Debido a que los campos en las instancias de mensajes protobuf tienen valores predeterminados, no es necesario siempre es intuitivo para saber si un campo se ha configurado o no.
- Mensajes proto-plus
# Use the "in" operator. has_field = "name" in campaign
- Mensajes de protobuf
campaign = client.get_type("Campaign") # Determines whether "name" is set and not just an empty string. campaign.HasField("name")
El protobuf
Message
de clase tiene un método HasField
que determina si el campo en una
mensaje, aunque se haya establecido en un valor predeterminado.
Métodos de mensajes de protobuf
La interfaz de mensajes protobuf incluye algunos métodos útiles que no son parte de la interfaz proto-plus; Sin embargo, es fácil acceder a ellos y convertir un mensaje proto-plus en su contraparte 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())
Seguimiento de problemas
Si tienes preguntas sobre estos cambios o problemas para migrar a
versión 14.0.0
de la biblioteca, presenta una
problema en nuestra
de Google.