Question

Is there a more Pythonic (2.7) way to check the server for a good status_code (200) that doesn't include using while True? My code snippet is as follows - and it's called many times:

    import time
    import json
    from datetime import datetime
    import requests

    while True:
        response = requests.get('http://example.com')
        if response.status_code != 200:
            print 'sleeping:',str(datetime.now()),response.status_code
            print 'sleeping:',str(datetime.now()),response.headers
            time.sleep(5.0)
        else: break
    if "x-mashery-error-code" in response.headers:
        return None
    return response.json()

edit: I included the 'if' loop with the header errors.

Was it helpful?

Solution

You can use Event Hooks

requests.get('http://example.com', hooks=dict(response=check_status))
def check_status(response):
    if response.status_code != 200:
        print 'not yet'

OTHER TIPS

I would like this solution:

response = requests.get('http://example.com')
while response.status_code != 200:
    print 'sleeping:',str(datetime.now()),response.status_code
    print 'sleeping:',str(datetime.now()),response.headers
    time.sleep(5.0)
    response = requests.get('http://example.com')

Because:

>>> import this
...
Explicit is better than implicit.
Simple is better than complex.
...
Flat is better than nested.
...
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
...
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
...

Because I read it and understand it right away. With event hooks this is not the case. Do they open a thread to retrieve bytes in parallel? When are they called? Do I need to retrieve the data myself?

I'm using aspect-oriented programming by applying decorators for things like doing retries. If my function for getting the value I want looks like this:

def getValue():
  return requests.get('http://example.com')

Then I'm decorating this function to apply the retry mechanism without interfering with the original (naive) code:

def retryUntilCondition(condition):
  def decorate(function):
    def f(*args, **kwargs):
      while True:
        result = function(*args, **kwargs)
        if condition(result):
          return result
        time.sleep(5.0)
    return f
  return decorate

def responseIs200(response):
  return response.status_code == 200

The above is the preparation (part of a utility library), below follows the usage:

@retryUntilCondition(responseIs200)
def getValue():
  return requests.get('http://example.com')

This way the while loop is completely hidden from the application code and does not complicate reading it. The aspect of retrying is added by prepending a simple decorator which can even be reused in other situations.

If later you decide that you only want to retry for a specific number of times, have different delays etc., all this can be implemented in the retry decorator alone.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top