Itérateurs de flux

La méthode search_stream renvoie un itérateur d' SearchGoogleAdsStreamResponse objets.

Vous pouvez parcourir chaque GoogleAdsRow dans le champ results de chaque réponse, comme illustré dans cet exemple de code.

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 structure de chaque GoogleAdsRow est déterminée par les champs que vous sélectionnez dans votre requête Google Ads Query Language (GAQL). Pour en savoir plus sur la structure de la réponse, consultez la page Google Ads Query Language.

Lorsque vous appelez GoogleAdsService.search_stream, un itérateur de réponse en streaming est renvoyé. Cet itérateur doit rester dans le même champ d'application que le client GoogleAdsService lorsqu'il est utilisé afin d'éviter les flux interrompus ou les erreurs de segmentation. En effet, l'objet gRPC Channel est collecté une fois que l'objet GoogleAdsService ouvert sort du champ d'application. Si l'objet GoogleAdsService n'est plus dans le champ d'application au moment où l'itération se produit sur le résultat de search_stream, l'objet Channel peut déjà être détruit, ce qui entraîne un comportement indéfini lorsque l'itérateur tente de récupérer la valeur suivante.

Le code suivant illustre une utilisation incorrecte des itérateurs de streaming :

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.

Dans ce code, l'objet GoogleAdsService est créé dans un champ d'application différent de celui où l'itérateur est accessible. Par conséquent, l'objet Channel peut être détruit avant que l'itérateur ne consomme l'intégralité de la réponse.

Au lieu de cela, l'itérateur de streaming doit rester dans le même champ d'application que le client GoogleAdsService tant qu'il est utilisé :

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.