Опрос конечной точки API - как повторить попытку, если не возвращен JSON? - PullRequest
0 голосов
/ 06 марта 2019

Я опрашиваю конечную точку API, используя цикл while, который проверяет, возвращает ли метод .get () в JSON значение None:

    while requests.get(render_execution_url, headers=headers).json().get('finalized_at') is None:
        status = requests.get(render_execution_url, headers=headers).json().get('status')
        status_detail = requests.get(render_execution_url, headers=headers).json().get('status_detail')
        logger.info("status for {} is {}.  detailed status is {}".format(render_execution_url, status, status_detail))

Идея в том, что мы продолжаем опрашиватьконечная точка, пока не будет заполнено значение «finalized_at».

К сожалению, мы периодически получаем сбои, когда JSON вообще не существует:

 File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
   return _default_decoder.decode(s)
 File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
   obj, end = self.raw_decode(s, idx=_w(s, 0).end())
 File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
   raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

Я пытался использовать декоратор повторов наметод (см. ниже для синтаксиса декоратора), но он, кажется, не выполняет повторных попыток, когда я столкнулся с этой ошибкой.

@retry(stop_max_attempt_number=7, wait_fixed=10000)

Есть ли изящный, Pythonic способ справиться со случаем, когда JSONне существует (то есть, чтобы повторить попытку через некоторое время)?

1 Ответ

2 голосов
/ 06 марта 2019

Ваш код слишком плотный, чтобы легко выделить различные условия, которые вам нужно обработать, и поэтому в вашем отчете об ошибках не ясно, что именно означает «когда JSON вообще не существует» - это сервер, возвращающий404 (страница не найдена), или данные ответа пусты, или что-то еще?

Вот перезапись, которая не обращается к URL для каждого доступа к JSON.Это может не совсем соответствовать вашим потребностям, но это должно дать вам начало.

while True:
    resp = requests.get(render_execution_url, headers=headers)
    # I assume response status is always 200 or 204 -
    # Really easy to detect a 404 here if that happens.
    if not resp.data:
        time.sleep(WAIT_TIME)
        continue
    rj = resp.json()
    if rj.get('finalized_at') is not None:
        break
    status = rj.get('status')
    status_detail = rj.get('status_detail')
    logger.info("status for {} is {}.  detailed status is {}"
                .format(render_execution_url, status, status_detail))
    time.sleep(WAIT_TIME)
...