Reputation: 25331
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.
Upvotes: 4
Views: 9204
Reputation: 59426
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.
Upvotes: 1
Reputation: 14873
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?
Upvotes: 3
Reputation: 56
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'
Upvotes: 4