تعلیق

کتابخانه کارخواه برای Python هیچ مهلت زمانی پیش‌فرضی را مشخص نمی‌کند و هیچ پیش‌فرضی نیز در لایه انتقال gRPC مشخص نشده است. به‌طور پیش‌فرض، کتابخانه کارخواه برای Python رفتار مهلت زمانی را به سرور واگذار می‌کند.

این پیش‌فرض برای اکثر موارد استفاده کاربرد دارد. بااین‌حال، اگر لازم است زمان استراحت سمت کارخواه را مشخص کنید، کتابخانه کارخواه Python از لغو زمان استراحت برای هر درخواست (که به ثانیه به‌عنوان int یا float مشخص می‌شود) برای تماس‌های جریانی و تکی پشتیبانی می‌کند. زمان‌های استراحت پیش‌فرض در سراسر کارخواه را نمی‌توان در google-ads.yaml پیکربندی کرد.

می‌توانید زمان اتمام سفارشی را روی ۲ ساعت (۷۲۰۰ ثانیه) یا بیشتر تنظیم کنید، اما API ممکن است همچنان درخواست‌های بسیار طولانی را به‌دلیل اتمام زمان لغو کند و خطای وضعیت gRPC DEADLINE_EXCEEDED را برگرداند. اگر این موضوع به مشکل تبدیل شد، پُرسمان را به بخش‌های کوچک‌تر تقسیم کنید و آن‌ها را به‌صورت موازی اجرا کنید؛ این کار از وضعیتی که در آن درخواست طولانی‌مدت ناموفق می‌شود و تنها راه بازیابی، راه‌اندازی مجدد درخواست از ابتدا است، جلوگیری می‌کند.

پایان مهلت تماس جاری‌سازی

تنها روش سرویس 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.

برای لغو کردن تنظیمات پیش‌فرض مهلت و تکرار مجدد برای تماس تک‌مقداری، شیء google.api_core.retry.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)}")