1

I'm building a web app that calls API. The API I'm currently using currently (it fluctuates) has a respawn time (probable not the correct term) of 210 seconds.

The API call in requests is:

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

After the call r can equal <Response [404]> or <Response [200]>. I want to run this API call until it returns a <Response [200]>. What format is <Response [200]> in?

My current loop is as follows. Is there a better way to do this?

while True:
    r = requests.post(url ,headers=headers, auth=auth, data=json.dumps(data))
    if (r == '<Response [200]>'): break
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
IdeoREX
  • 1,455
  • 5
  • 22
  • 39
  • 1
    Just so you know, I changed the mentions of "Django" to "requests" in your question. The question you asked is related to the ["requests"](http://docs.python-requests.org/en/latest/) library that you are using to make the calls. I'm not sure where Django comes into play here (perhaps it's used by the API you're calling, or maybe your code runs as part of a Django app), but your question is really about how the requests library works. – Mark Hildreth Aug 08 '13 at 17:04

2 Answers2

7

You are confusing the repr() output with the object.

Response objects have a .status_code attribute, test against that:

if r.status_code == 200:
    break

However, to hammer a service repeatedly until it gives you a 200 response is likely to get your IP address blocked. Build in some kind of exponential back-off to prevent DOS-ing the API.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I was about 5 mins late in reading this answer. Ya, I hammered the system. Thanks for the response. I need to find a way to have a 60 second delay in the loop – IdeoREX Aug 08 '13 at 17:07
  • 1
    @IdeoREX: `time.sleep(60)`, but that's not very web-friendly. Use an async task that reschedules itself with increasing intervals (using Celery, perhaps). – Martijn Pieters Aug 08 '13 at 17:09
0

I just shared a solution at https://stackoverflow.com/a/40918529/2398354 which might be worth repeating here.

You could try using requests HTTPAdapter. Something like the following should work:

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')
Community
  • 1
  • 1
TomDotTom
  • 6,238
  • 3
  • 41
  • 39