超时

Python 的客户端库未指定任何默认超时,gRPC 传输层也没有指定任何默认值。默认情况下,Python 的客户端库会将超时行为委托给服务器。

此默认值适用于大多数用例。不过,如果您需要指定客户端超时,Python 客户端库支持为流式调用和一元调用指定每个请求的超时替换(以秒 为单位,指定为 int 或 float)。无法在 google-ads.yaml 中配置客户端范围的默认超时。

您可以将自定义超时设置为 2 小时(7,200 秒)或更长时间,但 API 仍可能会让运行时间极长的请求超时,并返回 DEADLINE_EXCEEDED gRPC 状态错误。如果这成为一个问题,请将查询拆分为较小的块并并行执行;这样可以避免长时间运行的请求失败,并且唯一恢复方法是从头开始重新启动请求。

流式调用超时

唯一使用响应流的 Google Ads API 服务方法是 GoogleAdsService.SearchStream。

如需替换默认超时,请在调用该方法时传递 timeout 参数(以秒为单位):

def make_server_streaming_call(
    client: GoogleAdsClient, customer_id: str
) -> None:
    """Makes a server streaming call using a custom client timeout.

    Args:
        client: An initialized GoogleAds client.
        customer_id: The str Google Ads customer ID.
    """
    ga_service: GoogleAdsServiceClient = client.get_service("GoogleAdsService")
    campaign_ids: List[str] = []

    try:
        search_request: SearchGoogleAdsStreamRequest = client.get_type(
            "SearchGoogleAdsStreamRequest"
        )
        search_request.customer_id = customer_id
        search_request.query = _QUERY
        stream: Iterator[SearchGoogleAdsStreamResponse] = (
            ga_service.search_stream(
                request=search_request,
                # When making any request, an optional "timeout" parameter can be
                # provided to specify a client-side response deadline in seconds.
                # If not set, then no timeout will be enforced by the client and
                # the channel will remain open until the response is completed or
                # severed, either manually or by the server.
                timeout=_CLIENT_TIMEOUT_SECONDS,
            )
        )

        batch: SearchGoogleAdsStreamResponse
        for batch in stream:
            row: GoogleAdsRow
            for row in batch.results:
                campaign_ids.append(row.campaign.id)

        print("The server streaming call completed before the timeout.")
    except DeadlineExceeded:
        print("The server streaming call did not complete before the timeout.")
        sys.exit(1)
    except GoogleAdsException as ex:
        print(
            f"Request with ID '{ex.request_id}' failed with status "
            f"'{ex.error.code().name}' and includes the following errors:"
        )
        for error in ex.failure.errors:
            print(f"\tError with message '{error.message}'.")
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f"\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)

    print(f"Total # of campaign IDs retrieved: {len(campaign_ids)}")
      

一元调用超时

大多数 Google Ads API 服务方法都使用一元调用;典型示例包括 GoogleAdsService.Search 和 GoogleAdsService.Mutate。

如需替换一元调用的默认截止时间和重试设置,请使用retry参数传递 google.api_core.retry.Retry对象(或传递 timeout以秒为单位以实现单次尝试超时):

def make_unary_call(client: GoogleAdsClient, customer_id: str) -> None:
    """Makes a unary call using a custom client timeout.

    Args:
        client: An initialized GoogleAds client.
        customer_id: The Google Ads customer ID.
    """
    ga_service: GoogleAdsServiceClient = client.get_service("GoogleAdsService")
    campaign_ids: List[str] = []

    try:
        search_request: SearchGoogleAdsRequest = client.get_type(
            "SearchGoogleAdsRequest"
        )
        search_request.customer_id = customer_id
        search_request.query = _QUERY
        results: Iterator[GoogleAdsRow] = ga_service.search(
            request=search_request,
            # When making any request, an optional "retry" parameter can be
            # provided to specify its retry behavior. Complete information about
            # these settings can be found here:
            # https://googleapis.dev/python/google-api-core/latest/retry.html
            retry=Retry(
                # Sets the maximum accumulative timeout of the call; it
                # includes all tries.
                deadline=_CLIENT_TIMEOUT_SECONDS,
                # Sets the timeout that is used for the first try to one tenth
                # of the maximum accumulative timeout of the call.
                # Note: This overrides the default value and can lead to
                # RequestError.RPC_DEADLINE_TOO_SHORT errors when too small. We
                # recommend changing the value only if necessary.
                initial=_CLIENT_TIMEOUT_SECONDS / 10,
                # Sets the maximum timeout that can be used for any given try
                # to one fifth of the maximum accumulative timeout of the call
                # (two times greater than the timeout that is needed for the
                # first try).
                maximum=_CLIENT_TIMEOUT_SECONDS / 5,
            ),
        )

        row: GoogleAdsRow
        for row in results:
            campaign_ids.append(row.campaign.id)

        print("The unary call completed before the timeout.")
    except DeadlineExceeded:
        print("The unary call did not complete before the timeout.")
        sys.exit(1)
    except GoogleAdsException as ex:
        print(
            f"Request with ID '{ex.request_id}' failed with status "
            f"'{ex.error.code().name}' and includes the following errors:"
        )
        for error in ex.failure.errors:
            print(f"\tError with message '{error.message}'.")
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f"\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)

    print(f"Total # of campaign IDs retrieved: {len(campaign_ids)}")