Wersja 14.0.0
biblioteki klienta Pythona wprowadza nowy wymagany parametr konfiguracji o nazwie use_proto_plus
, który określa, czy biblioteka ma zwracać wiadomości proto-plus czy wiadomości protobuf. Szczegółowe informacje o ustawianiu tego parametru znajdziesz w dokumentacji konfiguracji.
Ta sekcja opisuje wpływ wyboru typów komunikatów na wydajność, dlatego zalecamy zapoznanie się z dostępnymi opcjami, aby podjąć świadomą decyzję. Jeśli jednak chcesz uaktualnić go do wersji 14.0.0
bez wprowadzania zmian w kodzie, możesz ustawić parametr use_proto_plus
na True
, aby uniknąć zmian w interfejsie.
Wiadomości protoplus i protobuf
W wersji 10.0.0
biblioteka klienta w Pythonie została przeniesiona do nowego potoku generatora kodu, który zintegrował proto-plus w celu poprawy ergonomii interfejsu wiadomości protobuf przez zmianę ich działania w sposób podobny do natywnych obiektów Pythona. Kompromisem tego ulepszenia jest to,
że proto-plus wprowadza wymagania dotyczące wydajności.
Wydajność Proto-plus
Jedną z głównych zalet proto-plusa jest to, że konwertuje wiadomości protobuf i dobrze znane typy na natywne typy Pythona przy użyciu protokołu typu marshall.
Organizowanie ma miejsce, gdy dostęp do pola uzyskuje się w instancji wiadomości proto-plus, zwłaszcza gdy pole jest odczytywane lub ustawione, na przykład w definicji protokołu:
syntax = "proto3";
message Dog {
string name = 1;
}
Po przekonwertowaniu tej definicji na klasę proto-plus będzie ona wyglądać mniej więcej tak:
import proto
class Dog(proto.Message):
name = proto.Field(proto.STRING, number=1)
Następnie możesz zainicjować klasę Dog
i uzyskać dostęp do jej pola name
tak jak w przypadku każdego innego obiektu Pythona:
dog = Dog()
dog.name = "Scruffy"
print(dog.name)
Podczas odczytywania i ustawiania pola name
wartość jest konwertowana z natywnego typu str
w Pythonie na string
, co zapewnia zgodność ze środowiskiem wykonawczym protobuf.
W analizie przeprowadzonej od momentu opublikowania wersji 10.0.0
stwierdziliśmy, że czas poświęcony na przeprowadzanie konwersji tego typu ma na tyle duży wpływ na skuteczność, że ważne jest zapewnienie użytkownikom możliwości korzystania z wiadomości protobuf.
Przypadki użycia wiadomości proto-plus i protobuf
- Przypadki użycia wiadomości Proto-plus
- Proto-plus ma szereg ergonomicznych ulepszeń w porównaniu z protobufami, dzięki czemu idealnie nadaje się do pisania łatwego w użyciu i czytelnego kodu. Ponieważ ujawniają one natywne obiekty Pythona, są łatwiejsze w użyciu i zrozumieniu.
- Przypadki użycia wiadomości w protobuf
- Używaj protokołów w przypadkach użycia związanych z wydajnością, zwłaszcza w aplikacjach, w których musisz szybko przetwarzać duże raporty lub które tworzą żądania mutacji obejmujące dużą liczbę operacji, np. w
BatchJobService
lubOfflineUserDataJobService
.
Dynamicznie zmieniające się typy wiadomości
Po wybraniu odpowiedniego typu wiadomości dla swojej aplikacji może się okazać, że musisz użyć innego typu w określonym przepływie pracy. W tym przypadku można łatwo przełączać się między tymi dwoma typami funkcji, korzystając z narzędzi dostępnych w bibliotece klienta. Użycie tej samej klasy wiadomości Dog
z podanej wyżej listy:
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)
Różnice w interfejsie komunikatów w protobuf
Interfejs proto-plus jest szczegółowo opisany, ale tutaj omówimy kilka najważniejszych różnic, które mają wpływ na typowe przypadki użycia biblioteki klienta Google Ads.
Serializacja bajtów
- Wiadomości Proto-plus
serialized = type(campaign).serialize(campaign) deserialized = type(campaign).deserialize(serialized)
- Wiadomości w protokole Protobuf
serialized = campaign.SerializeToString() deserialized = campaign.FromString(serialized)
Serializacja JSON
- Wiadomości Proto-plus
serialized = type(campaign).to_json(campaign) deserialized = type(campaign).from_json(serialized)
- Wiadomości w protokole Protobuf
from google.protobuf.json_format import MessageToJson, Parse serialized = MessageToJson(campaign) deserialized = Parse(serialized, campaign)
Maski pól
Metoda pomocnicza maski pól udostępniana przez api-core jest przeznaczona do korzystania z instancji wiadomości protobuf. Jeśli więc używasz wiadomości proto-plus, przekonwertuj je na wiadomości protobuf, aby użyć wiadomości pomocniczej:
- Wiadomości 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)
- Wiadomości w protokole Protobuf
from google.api_core.protobuf_helpers import field_mask campaign = client.get_type("Campaign") mask = field_mask(None, campaign)
Wartości w polu enum
Wyliczenia widoczne dla wiadomości proto-plus to instancje natywnego typu enum
Pythona, więc dziedziczą one szereg udogodnień.
Pobieranie typu wyliczenia
W przypadku pobierania wyliczeń za pomocą metody GoogleAdsClient.get_type
zwracane wiadomości różnią się nieco w zależności od tego, czy używasz wiadomości proto-plus, czy protobuf. Na przykład:
- Wiadomości Proto-plus
val = client.get_type("CampaignStatusEnum").CampaignStatus.PAUSED
- Wiadomości w protokole Protobuf
val = client.get_type("CampaignStatusEnum").PAUSED
Aby uprościć pobieranie wyliczeń, wprowadziliśmy atrybut udogodnień w instancjach GoogleAdsClient
, które mają spójny interfejs niezależnie od używanego typu wiadomości:
val = client.enums.CampaignStatusEnum.PAUSED
Pobranie wartości wyliczenia
Czasami warto znać wartość lub identyfikator pola danej wyliczenia. Na przykład PAUSED
w CampaignStatusEnum
odpowiada wartości 3
:
- Wiadomości Proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the value of campaign status print(campaign.status.value)
- Wiadomości w protokole 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))
Pobranie nazwy w Enum
Czasami warto znać nazwę pola wyliczenia. Na przykład podczas odczytywania obiektów z interfejsu API możesz chcieć się dowiedzieć, któremu stanowi kampanii odpowiada intencja 3
:
- Wiadomości Proto-plus
campaign = client.get_type("Campaign") campaign.status = client.enums.CampaignStatusEnum.PAUSED # To read the name of campaign status print(campaign.status.name)
- Wiadomości w protokole 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)
Pola powtarzane
Jak opisano w dokumentacji protokołu, pola powtarzane są zasadniczo równoważne z listami wpisanymi, co oznacza, że działają prawie identycznie jak pola list
.
Dołączam do powtarzających się pól skalarnych
W przypadku dodawania wartości do powtarzających się pól typu skalarnego, np. pól string
lub int64
, interfejs jest taki sam niezależnie od typu komunikatu:
- Wiadomości Proto-plus
ad.final_urls.append("https://www.example.com")
- Wiadomości w protokole Protobuf
ad.final_urls.append("https://www.example.com")
Obejmuje to też wszystkie inne popularne metody list
, np. extend
:
- Wiadomości Proto-plus
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
- Wiadomości w protokole Protobuf
ad.final_urls.extend(["https://www.example.com", "https://www.example.com/2"])
Dołączanie typów wiadomości do pól powtarzanych
Jeśli pole powtarzane nie jest typem skalarnym, działanie podczas dodawania ich do powtarzanych pól jest nieco inne:
- Wiadomości Proto-plus
frequency_cap = client.get_type("FrequencyCapEntry") frequency_cap.cap = 100 campaign.frequency_caps.append(frequency_cap)
- Wiadomości w protokole Protobuf
# The add method initializes a message and adds it to the repeated field frequency_cap = campaign.frequency_caps.add() frequency_cap.cap = 100
Przypisywanie pól powtarzanych
Zarówno w skalarnych, jak i nieskalarnych polach powtarzanych możesz przypisywać listy do pola na różne sposoby:
- Wiadomości Proto-plus
# In proto-plus it's possible to use assignment. urls = ["https://www.example.com"] ad.final_urls = urls
- Wiadomości w protokole 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
Puste wiadomości
Czasami warto sprawdzić, czy instancja wiadomości zawiera jakiekolwiek informacje lub czy ma ustawione któreś z jej pól.
- Wiadomości Proto-plus
# When using proto-plus messages you can simply check the message for # truthiness. is_empty = bool(campaign) is_empty = not campaign
- Wiadomości w protokole Protobuf
is_empty = campaign.ByteSize() == 0
Kopiowanie wiadomości
W przypadku wiadomości proto-plus i protobufów zalecamy użycie metody pomocniczej copy_from
w interfejsie GoogleAdsClient
:
client.copy_from(campaign, other_campaign)
Puste pola wiadomości
Proces ustawiania pustych pól wiadomości jest taki sam niezależnie od używanego typu wiadomości. Wystarczy skopiować pustą wiadomość w odpowiednie pole. Zapoznaj się z sekcją Tekst wiadomości i przewodnikiem Puste pola wiadomości. Oto przykład ustawiania pustego pola wiadomości:
client.copy_from(campaign.manual_cpm, client.get_type("ManualCpm"))
Nazwy pól, które są zarezerwowanymi słowami
Gdy używasz wiadomości proto-plus, nazwy pól są automatycznie wyświetlane ze znakiem na końcu, jeśli jest ona również słowem zarezerwowanym w Pythonie. Oto przykład pracy z instancją Asset
:
asset = client.get_type("Asset")
asset.type_ = client.enums.AssetTypeEnum.IMAGE
Pełna lista zarezerwowanych nazw jest tworzona w module generatora GApic. Można też uzyskać do nich dostęp automatycznie.
Najpierw zainstaluj moduł:
python -m pip install gapic-generator
Następnie w języku REPL lub skrypcie w Pythonie:
import gapic.utils
print(gapic.utils.reserved_names.RESERVED_NAMES)
Obecność pól
Pola w instancjach wiadomości w protokole protobuf mają wartości domyślne, dlatego nie zawsze można sprawdzić, czy pole zostało ustawione.
- Wiadomości Proto-plus
# Use the "in" operator. has_field = "name" in campaign
- Wiadomości w protokole Protobuf
campaign = client.get_type("Campaign") # Determines whether "name" is set and not just an empty string. campaign.HasField("name")
Interfejs klasy protobuf Message
zawiera metodę HasField
, która określa, czy pole w wiadomości zostało ustawione, nawet jeśli ustawiono wartość domyślną.
Metody wysyłania wiadomości w protobufach
Interfejs wiadomości w protokole protobuf zawiera pewne wygodne metody, które nie są częścią interfejsu protoplus. Aby uzyskać do nich dostęp, wystarczy skonwertować wiadomość proto-plus na jej odpowiednik w protokole 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())
Śledzenie problemów
Jeśli masz pytania dotyczące tych zmian lub masz problemy z przejściem na wersję 14.0.0
biblioteki, zgłoś problem w naszym trackerze.