Utiliser « while True » lors d'une requête http dans Python 2.7
-
21-12-2019 - |
Question
Existe-t-il un moyen plus pythonique (2.7) de vérifier sur le serveur un bon status_code (200) qui n'inclut pas l'utilisation while True
?Mon extrait de code est le suivant - et il est appelé plusieurs fois :
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()
modifier: J'ai inclus la boucle « if » avec les erreurs d'en-tête.
La solution
Vous pouvez utiliser Crochets d’événement
requests.get('http://example.com', hooks=dict(response=check_status))
def check_status(response):
if response.status_code != 200:
print 'not yet'
Autres conseils
Je voudrais cette 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')
Parce que:
>>> 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.
...
Parce que je l'ai lu et je comprends tout de suite.Avec les hooks d'événements, ce n'est pas le cas.Est-ce qu'ils ouvrent un thread pour récupérer des octets en parallèle ?Quand sont-ils appelés ?Dois-je récupérer les données moi-même ?
J'utilise une programmation orientée aspect en appliquant des décorateurs pour des choses comme faire des tentatives.Si ma fonction pour obtenir la valeur souhaitée ressemble à ceci :
def getValue():
return requests.get('http://example.com')
Ensuite, je décore cette fonction pour appliquer le mécanisme de nouvelle tentative sans interférer avec le code original (naïf) :
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
Ce qui précède est la préparation (qui fait partie d'une bibliothèque d'utilitaires), ci-dessous suit l'utilisation :
@retryUntilCondition(responseIs200)
def getValue():
return requests.get('http://example.com')
De cette façon le while
La boucle est complètement cachée du code de l'application et ne complique pas sa lecture.Le aspect de réessayer est ajouté en ajoutant un simple décorateur qui peut même être réutilisé dans d'autres situations.
Si plus tard vous décidez que vous souhaitez réessayer seulement un certain nombre de fois, avoir des délais différents, etc., tout cela peut être implémenté dans le retry
décorateur seul.