Itérateurs de flux de réponse

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

Parcourir les réponses de flux

Vous pouvez parcourir chaque GoogleAdsRow dans le champ results de chaque réponse, comme illustré dans l'exemple de code suivant :

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 GAQL (Google Ads Query Language). Pour en savoir plus sur la structure de la réponse, consultez la page Langage de requête Google Ads.

Conserver l'itérateur dans le champ d'application

Lorsque vous appelez GoogleAdsService.search_stream, un itérateur de réponse de flux est renvoyé. Cet itérateur doit rester dans le même champ d'application que le client GoogleAdsService pendant son utilisation pour éviter les flux interrompus ou les erreurs de segmentation. En effet, l'objet Channel gRPC sous-jacent est collecté une fois que l'objet GoogleAdsService ouvert n'est plus dans le champ d'application. Si l'objet GoogleAdsService n'est plus dans le champ d'application lorsque 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 flux :

def stream_response(client, customer_id, query):
    # The GoogleAdsService instance goes out of scope when this function
    # returns.
    ga_service = client.get_service(
        "GoogleAdsService", version="v26"
    )
    return ga_service.search_stream(customer_id=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)

    # Accessing the iterator in a different scope from where the service object
    # was created results in undefined behavior.
    for batch in response:
        print(batch)

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.

Conservez plutôt l'itérateur de flux 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="v26"
    )
    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 where the service object was
    # created.
    for batch in response:
        print(batch)