2013-08-08 1 views
0

Я создаю веб-приложение, которое вызывает API. API, который я использую в настоящее время (он колеблется) имеет время респауна (вероятно, не правильный термин) в 210 секунд.Retry <Response [404]> до тех пор, пока я не получу <Response [200]>

вызов API-запросов в это:

r = requests.post(url ,headers=headers, auth=auth, data=json.dumps(data)) 

После вызова r может равняться <Response [404]> или <Response [200]>. Я хочу запустить этот вызов API, пока он не вернет <Response [200]>. Какой формат: <Response [200]>?

My current loop выглядит следующим образом. Есть лучший способ сделать это?

while True: 
    r = requests.post(url ,headers=headers, auth=auth, data=json.dumps(data)) 
    if (r == '<Response [200]>'): break 
+1

Просто, чтобы вы знали, я изменил упоминания «Django» на «запросы» в вашем вопросе. Заданный вами вопрос связан с библиотекой ["запросов"] (http://docs.python-requests.org/en/latest/), которую вы используете для совершения вызовов. Я не уверен, где Django играет здесь (возможно, он используется API, который вы вызываете, или, может быть, ваш код работает как часть приложения Django), но ваш вопрос действительно о том, как работает библиотека запросов. –

ответ

5

Вы путаете вывод repr() с объектом.

объекты Response имеют .status_code attribute, тест против этого:

if r.status_code == 200: 
    break 

Однако забивать сервис несколько раз, пока она не дает вам ответ 200, скорее всего, чтобы получить ваш IP-адрес заблокирован. Постройте в некотором виде exponential back-off, чтобы предотвратить использование DOS-интерфейса API.

+0

Мне было около 5 минут в конце этого прочтения. Я, я забил систему. Спасибо за ответ. Мне нужно найти способ иметь 60-секундную задержку в цикле – IdeoREX

+1

@IdeoREX: 'time.sleep (60)', но это не очень удобно для веб-интерфейса. Используйте задачу async, которая перестраивается с увеличением интервалов (возможно, с использованием Celery). –

0

Я только что получил решение по адресу https://stackoverflow.com/a/40918529/2398354, которое, возможно, стоит здесь повторить.

Вы можете попробовать использовать HTTPAdapter. Что-то вроде следующего должно работать:

import time 
import httplib 

import requests 
from requests.adapters import HTTPAdapter 


class RetryHTTPAdapter(HTTPAdapter): 

    SECONDS_BETWEEN_RETRIES = 5 

    def __init__(self, retry_time=120, *args, **kwargs): 
     self.retry_time = retry_time 
     super(RetryHTTPAdapter, self).__init__(*args, **kwargs) 

    def send(self, *args, **kwargs): 
     for _ in range(int(self.retry_time/self.SECONDS_BETWEEN_RETRIES)): 
      response = super(RetryHTTPAdapter, self).send(*args, **kwargs) 
      if response.status_code == httplib.OK: 
       break 
      time.sleep(self.SECONDS_BETWEEN_RETRIES) 
     return response 

s = requests.Session() 
s.mount('http://', RetryHTTPAdapter(retry_time=180)) 
s.mount('https://', RetryHTTPAdapter(retry_time=180)) 

s.get('http://example.com') 
Смежные вопросы