Version
14.0.0
de la bibliothèque cliente Python introduit un nouveau paramètre de configuration obligatoire
appelé use_proto_plus
, qui spécifie si vous souhaitez que la bibliothèque
messages proto-plus ou
messages protobuf. Pour en savoir plus sur
comment définir ce paramètre, consultez la documentation sur la configuration.
Cette section décrit les implications sur les performances du choix des types
les messages à utiliser. C'est pourquoi nous vous recommandons de lire et de comprendre
les options afin de
prendre une décision éclairée. Toutefois, si vous souhaitez
passer à la version 14.0.0
sans modifier le code, vous pouvez définir
use_proto_plus
à True
pour éviter d'endommager les modifications de l'interface.
Messages proto-plus et messages protobuf
Dans la version 10.0.0
, la bibliothèque cliente Python a migré vers un nouveau générateur de code
qui intégrait
proto-plus comme moyen d'améliorer
l'ergonomie de l'interface de message
des tampons de protocole en les rendant plus
comme les objets Python natifs. La contrepartie de cette
amélioration est que proto-plus
entraîne une surcharge des performances.
Performances protoplus
L'un des principaux avantages de proto-plus est qu'il convertit les protobufs messages et les types connus pour des types Python natifs via un processus appelé type le marshaling.
Le marshaling se produit lorsqu'un champ est consulté sur une instance de message proto-plus, en particulier lorsqu'un champ est lu ou défini, par exemple dans un tampon de protocole définition:
syntax = "proto3";
message Dog {
string name = 1;
}
Lorsque cette définition est convertie en une classe proto-plus, elle a l'air comme ceci:
import proto
class Dog(proto.Message):
name = proto.Field(proto.STRING, number=1)
Vous pouvez ensuite initialiser la classe Dog
et accéder à son champ name
comme vous le feriez
tout autre objet Python:
dog = Dog()
dog.name = "Scruffy"
print(dog.name)
Lors de la lecture et de la définition du champ name
, la valeur est convertie à partir d'une valeur native
Python str
en type string
afin que
que la valeur est compatible avec
l'environnement d'exécution du tampon de protocole.
Dans l'analyse que nous avons menée depuis la sortie de la version 10.0.0
, nous avons :
nous avons déterminé que le temps passé à effectuer ces types de conversions
sur les performances. Il est donc important de donner aux utilisateurs la possibilité d'utiliser les tampons de protocole
messages.
Cas d'utilisation des messages proto-plus et protobuf
- Cas d'utilisation des messages proto-plus
- Proto-plus offre un certain nombre d'améliorations ergonomiques par rapport aux messages protobuf, Elles sont donc idéales pour écrire du code facile à gérer et lisible. Puisqu'ils exposent des objets Python natifs, ils sont plus faciles à utiliser et à comprendre.
- Cas d'utilisation des messages Protobuf
- Utilisez les tampons de protocole pour les cas d'utilisation sensibles aux performances, en particulier dans les applications
qui doivent traiter rapidement des rapports volumineux ou qui créent des demandes mutate avec une variable
un grand nombre d'opérations, par exemple
BatchJobService
ouOfflineUserDataJobService
Modification dynamique des types de messages
Après avoir sélectionné le type de message
approprié pour votre application,
que vous devez utiliser l'autre type
pour un workflow spécifique. Dans ce cas, il s'agit
passer facilement d'un type à l'autre de manière dynamique à l'aide des utilitaires proposés par le
bibliothèque cliente. Utiliser la même classe de message Dog
que ci-dessus:
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)
Différences entre l'interface des messages Protobuf
L'interface proto-plus est documentée dans détails, mais nous allons ici souligner Principales différences qui affectent les cas d'utilisation courants du client Google Ads bibliothèque.
Sérialisation des octets
- Messages proto-plus
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- Messages Protobuf
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
Sérialisation JSON
- Messages proto-plus
serialized = type(campaign).to_json(campaign) deserialized = type(campaign).from_json(serialized)
- Messages Protobuf
from google.protobuf.json_format import MessageToJson, Parse serialized = MessageToJson(campaign) deserialized = Parse(serialized, campaign)
Masques de champ
La méthode d'assistance de masque de champ fournie par api-core est conçu pour utiliser des tampons de protocole aux instances de message. Ainsi, lorsque vous utilisez des messages proto-plus, convertissez-les en protobuf pour utiliser l'application auxiliaire:
- Messages 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)
- Messages Protobuf
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") mask = field_mask(None, campaign)
Enums
Les énumérations exposées par les messages proto-plus sont des instances de l'environnement natif Python
enum
et donc
héritent d'un certain nombre de méthodes pratiques.
Récupération du type d'énumération
Lorsque vous utilisez la méthode GoogleAdsClient.get_type
pour récupérer des énumérations, les messages
qui sont renvoyés sont légèrement différents selon que vous utilisez
les messages proto-plus
ou protobuf. Exemple :
- Messages proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- Messages Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
Pour simplifier la récupération des énumérations, il existe un attribut de commodité sur
GoogleAdsClient
instances disposant d'une interface cohérente, quelles que soient
que vous utilisez:
val = client.enums.CampaignStatusEnum.PAUSED
Récupération des valeurs d'énumération
Il est parfois utile de connaître la valeur ou l'ID de champ d'une énumération donnée, pour
Par exemple, PAUSED
sur CampaignStatusEnum
correspond à 3
:
- Messages proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the value of campaign status print(campaign.status.value)
- Messages 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))
Récupération des noms d'énumérations
Il est parfois utile de connaître le nom d'un champ d'énumération. Par exemple, lorsque
les objets de lecture de l'API, vous pouvez connaître l'état de la campagne
La fonction int 3
correspond à:
- Messages proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the name of campaign status print(campaign.status.name)
- Messages 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)
Champs répétés
Comme décrit dans le document proto-plus
d'assistance,
Les champs répétés sont généralement équivalents aux listes typées, ce qui signifie qu'ils
se comportent presque de la même manière qu'une list
.
Ajout à des champs scalaires répétés
Lorsque vous ajoutez des valeurs à des valeurs scalaires répétées
type (par exemple,
string
ou int64
, l'interface est la même, quel que soit le message
type:
- Messages proto-plus
ad.final_urls.append("https://www.example.com")
- Messages Protobuf
ad.final_urls.append("https://www.example.com")
Cela inclut également toutes les autres méthodes list
courantes, par exemple extend
:
- Messages proto-plus
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
- Messages Protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Ajouter des types de messages à des champs répétés
Si le champ répété n'est pas de type scalaire type, le comportement appliqué lors de leur ajout avec les champs répétés est légèrement différente:
- Messages proto-plus
frequency_cap = client.get_type("FrequencyCapEntry") frequency_cap.cap = 100 campaign.frequency_caps.append(frequency_cap)
- Messages Protobuf
# The add method initializes a message and adds it to the repeated field frequency_cap = campaign.frequency_caps.add() frequency_cap.cap = 100
Attribuer des champs répétés
Pour les champs répétés scalaires et non scalaires, vous pouvez attribuer des listes au de différentes manières:
- Messages proto-plus
# In proto-plus it's possible to use assignment. urls = ["https://www.example.com"] ad.final_urls = urls
- Messages 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
Messages vides
Il est parfois utile de savoir si une instance de message contient ou si l'un de ses champs est défini.
- Messages proto-plus
# When using proto-plus messages you can simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not campaign
- Messages Protobuf
is_empty = campaign.ByteSize() == 0
Copie du message
Pour les messages proto-plus et protobuf, nous vous recommandons d'utiliser copy_from
sur la GoogleAdsClient
:
client.copy_from(campaign, other_campaign)
Champs du message vides
Le processus pour définir des champs de message vides est le même, quelle que soit la que vous utilisez. Il vous suffit de copier un message vide dans le champ en question. Consultez les sections Texte du message et Message vide Champs. Voici un exemple de la façon dont pour définir un champ de message vide:
client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))
Noms de champs contenant des mots réservés
Lors de l'utilisation de messages proto-plus, les noms de champs apparaissent automatiquement avec une
un trait de soulignement à la fin si le nom est également un mot réservé en Python. Voici un
exemple d'utilisation d'une instance Asset
:
asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE
La liste complète des noms est construite dans la gapique generator. Il peut s'agir également de manière programmatique.
Commencez par installer le module:
python -m pip install gapic-generator
Ensuite, dans un REPL ou un script Python:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
Présence sur le terrain
Comme les champs des instances de message protobuf ont des valeurs par défaut, il n'est pas toujours intuitive de savoir si un champ a été défini ou non.
- Messages proto-plus
# Use the "in" operator. has_field = "name" in campaign
- Messages Protobuf
campaign = client.get_type("Campaign") # Determines whether "name" is set and not just an empty string. campaign.HasField("name")
Protobuf
Message
comporte une méthode HasField
qui détermine si le champ d'une
a été défini, même s'il a été défini sur une valeur par défaut.
Méthodes de message Protobuf
L'interface de message protobuf comprend quelques méthodes pratiques qui ne sont pas de l'interface proto-plus ; Toutefois, il est facile d'y accéder convertir un message proto-plus en son équivalent 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())
Outil de suivi des problèmes
Si vous avez des questions sur ces modifications ou si vous rencontrez des problèmes lors de la migration vers
version 14.0.0
de la bibliothèque, envoyez une
problème sur notre
coach électronique.