Ловля 403 запрещено в Python - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть следующая функция для запуска извлечения данных BigQuery (см. Ниже). Когда я отправляю слишком много запросов, я получаю сообщение об ошибке:

google.api_core.exceptions.Forbidden: 403 Превышено ограничение скорости: слишком много одновременных запросов для этого project_and_region. Для большего информация, см. https://cloud.google.com/bigquery/troubleshooting-errors

Мне интересно, почему мой код не может перехватить запрещенную ошибку, поскольку я явно написал функцию для перехвата 403?


from google.cloud import bigquery
from google.api_core.exceptions import Forbidden, InternalServerError, ServiceUnavailable

def run_job(query, query_params, attempt_nb=1):

    # Configure
    job_config = bigquery.QueryJobConfig()
    job_config.query_parameters = query_params
    query_job = client.query(
        query,
        # Location must match that of the dataset(s) referenced in the query.
        location='US',
        job_config=job_config)  # API request - starts the query

    # Try to run and transform to DataFrame()
    try:
        df = query_job.to_dataframe()
        assert query_job.state == 'DONE'
        return df

    except Forbidden:
        # Exception mapping a ``403 Forbidden`` response."""
        return retry_job(query, query_params, attempt_nb)

    except InternalServerError:
        # Exception mapping a ``500 Internal Server Error`` response. or a :attr:`grpc.StatusCode.INTERNAL` error."""
        return retry_job(query, query_params, attempt_nb)

    except ServiceUnavailable:
        # Exception mapping a ``503 Service Unavailable`` response or a :attr:`grpc.StatusCode.UNAVAILABLE` error."""
        return retry_job(query, query_params, attempt_nb)


def retry_job(query, query_params, attempt_nb):
    # If the error is a rate limit or connection error, wait and
    # try again.
    # 403: Forbidden: Both access denied and rate limits.
    # 408: Timeout
    # 500: Internal Service Error
    # 503: Service Unavailable
    # Old way: if err.resp.status in [403, 408, 500, 503]:
    if attempt_nb < 3:
        print(' ! New BigQuery error. Retrying in 10s')
        time.sleep(10)
        return run_job(query, query_params, attempt_nb + 1)
    else:
        raise Exception('BigQuery error. Failed 3 times', query)

1 Ответ

2 голосов
/ 25 апреля 2019

Исключение, скорее всего, вызывается следующей строкой, а не внутри блока try.to_dataframe() может показаться виновником, если происходит повторная попытка, и исключение выдается снова во время рекурсии.

query_job = client.query(
    query,
    # Location must match that of the dataset(s) referenced in the query.
    location='US',
    job_config=job_config)  # API request - starts the query

Просмотр источника для этой библиотеки метод query() вызывает POST для создания задания, где rateLimitExceeded проверяется в соответствии со страницей Google на Устранение ошибок :

Эта ошибка возвращается, если ваш проект превышает лимит одновременной скорости или лимит запросов API, посылая слишком много запросов слишком быстро.

Вы можете дополнительно проверить это, добавив ведение журнала вызовов и / или поставивquery() вызов в блоке try, чтобы увидеть, решит ли это проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...