El método search_stream devuelve un iterador de objetos SearchGoogleAdsStreamResponse.
Puedes iterar cada GoogleAdsRow en el campo results de cada respuesta, como se muestra en este ejemplo de código.
def main(client: GoogleAdsClient, customer_id: str) -> None: ga_service: GoogleAdsServiceClient = client.get_service("GoogleAdsService") query: str = """ SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id""" # Issues a search request using streaming. stream: Iterator[SearchGoogleAdsStreamResponse] = ga_service.search_stream( customer_id=customer_id, query=query ) for batch in stream: rows: List[GoogleAdsRow] = batch.results for row in rows: print( f"Campaign with ID {row.campaign.id} and name " f'"{row.campaign.name}" was found.' )
La estructura de cada GoogleAdsRow se determina según los campos que selecciones en tu consulta del lenguaje de consultas de Google Ads (GAQL). Para obtener más detalles sobre la estructura de la respuesta, consulta el Lenguaje de consultas de Google Ads.
Cuando se llama a GoogleAdsService.search_stream, se devuelve un iterador de respuesta de transmisión. Este iterador debe permanecer en el mismo alcance que el cliente de GoogleAdsService mientras se usa para evitar flujos interrumpidos o errores de segmentación. Esto se debe a que el objeto Channel de gRPC se recopila como basura una vez que el objeto GoogleAdsService abierto queda fuera del alcance.
Si el objeto GoogleAdsService ya no está en el alcance cuando se produce la iteración en el resultado de search_stream, es posible que el objeto Channel ya se haya destruido, lo que provoca un comportamiento indefinido cuando el iterador intenta recuperar el siguiente valor.
En el siguiente código, se muestra el uso incorrecto de los iteradores de transmisión:
def stream_response(client, customer_id, query):
return client.get_service("GoogleAdsService", version="v24").search_stream(customer_id, query=query)
def main(client, customer_id):
query = "SELECT campaign.name FROM campaign LIMIT 10"
response = stream_response(client, customer_id, query=query)
# Access the iterator in a different scope from where the service object was created.
try:
for batch in response:
# Iterate through response, expect undefined behavior.
En este código, el objeto GoogleAdsService se crea dentro de un alcance diferente del lugar donde se accede al iterador. Como resultado, el objeto Channel puede destruirse antes de que el iterador consuma toda la respuesta.
En su lugar, el iterador de transmisión debe permanecer en el mismo alcance que el cliente de GoogleAdsService mientras se esté usando:
def main(client, customer_id):
ga_service = client.get_service("GoogleAdsService", version="v24")
query = "SELECT campaign.name FROM campaign LIMIT 10"
response = ga_service.search_stream(customer_id=customer_id, query=query)
# Access the iterator in the same scope as where the service object was created.
try:
for batch in response:
# Successfully iterate through response.