Moduł zapytań w Pythonie jest prosty i elegancki, ale jedno mnie wkurza. Możliwe jest uzyskanie requests.exception.ConnectionError z komunikatem:
Max retries exceeded with url: ...
Oznacza to, że żądania mogą próbować uzyskać dostęp do danych kilka razy. Ale nigdzie w dokumentacji nie ma ani jednej wzmianki o tej możliwości. Patrząc na kod źródłowy, nie znalazłem żadnego miejsca, w którym mógłbym zmienić domyślną (prawdopodobnie 0) wartość.
Czy można w jakiś sposób ustawić maksymalną liczbę ponownych żądań?
python
python-requests
Kirill Zaitsev
źródło
źródło
requests.get(url, max_retries=num_max_retries, dely_between_retries=3))
just.get
ijust.post
w github.com/kootenpv/justOdpowiedzi:
Jest to
urllib3
biblioteka podstawowa , która próbuje ponownie. Aby ustawić inną maksymalną liczbę ponownych prób, użyj alternatywnych adapterów transportowych :max_retries
Argumentu zajmuje całkowitą alboRetry()
obiekt ; ten ostatni zapewnia dokładną kontrolę nad tym, jakie rodzaje błędów są ponawiane (wartość całkowita jest przekształcana wRetry()
instancję, która obsługuje tylko awarie połączenia; błędy po nawiązaniu połączenia nie są domyślnie obsługiwane, ponieważ mogą one prowadzić do skutków ubocznych) .Stara odpowiedź, wcześniejsza niż wydanie żądań 1.2.1 :
requests
Biblioteka nie naprawdę to konfigurowalne, ani nie zamierza (patrz ten wniosek ciągnącego ). Obecnie (żądania 1.1) liczba ponownych prób jest ustawiona na 0. Jeśli naprawdę chcesz ustawić wyższą wartość, musisz ustawić to globalnie:Ta stała nie jest udokumentowana; używaj go na własne ryzyko, ponieważ przyszłe wydania mogą zmienić sposób, w jaki jest to obsługiwane.
Aktualizacja : i to się zmieniło; w wersji 1.2.1 dodano opcję ustawienia
max_retries
parametru dlaHTTPAdapter()
klasy , dzięki czemu teraz musisz użyć alternatywnych adapterów transportowych, patrz wyżej. Metoda małpiej łatki już nie działa, chyba że poprawisz takżeHTTPAdapter.__init__()
ustawienia domyślne (bardzo niezalecane).źródło
session.mount('http://', HTTPAdapter(max_retries=10))
będzie działać dla wszystkich połączeń HTTP. To samo z https będzie działać dla wszystkich połączeń https.http://
ihttps://
są minimalnymi prefiksami do użycia, zapoznaj się z dokumentacją, do której prowadzą łącza do odpowiedzi.HTTPAdapter(max_retries=5)
będzie działać tylko w przypadku niektórych scenariuszy. Z dokumentu żądania ,Note, this applies only to failed DNS lookups, socket connections and connection timeouts, never to requests where data has made it to the server. By default, Requests does not retry failed connections.
aby wymusić ponowienie próby dla kodów statusu, patrz odpowiedź @ datashaman poniżej.Retry()
aby zmienić, które scenariusze awarii są ponawiane.Spowoduje to nie tylko zmianę max_retries, ale także włączenie strategii wycofywania, która powoduje, że żądania do wszystkich adresów http: // są uśpione przez pewien czas przed ponowną próbą (w sumie 5 razy):
Zgodnie z dokumentacją dla
Retry
: jeśli współczynnik_offoff wynosi 0,1 , wówczas sleep () będzie spał przez [0,1s, 0,2s, 0,4s, ...] pomiędzy ponownymi próbami. Wymusi również ponowienie próby, jeśli zwrócony kod stanu to 500 , 502 , 503 lub 504 .Różne inne opcje
Retry
umożliwiające bardziej szczegółową kontrolę:MaxRetryError
lub zwrócić odpowiedź z kodem odpowiedzi w 3xx .Uwaga : raise_on_status jest stosunkowo nowy i nie wydał jeszcze wersji urllib3 ani żądań.raise_on_status argumentem kluczowe wydaje się, że znalazły się w standardowej biblioteki Pythona co najwyżej w wersji 3.6.Aby ponawiać żądania dla określonych kodów stanu HTTP, użyj status_forcelist . Na przykład status_forcelist = [503] spróbuje ponownie o kodzie stanu 503 (usługa niedostępna).
Domyślnie ponowna próba jest uruchamiana tylko dla następujących warunków:
TimeoutError
HTTPException
podniesiony (z http.client w Pythonie 3 jeszcze httplib ). Wydaje się, że są to wyjątki HTTP niskiego poziomu, takie jak nieprawidłowy adres URL lub protokół.SocketError
ProtocolError
Zauważ, że są to wszystkie wyjątki, które uniemożliwiają regularną odpowiedź HTTP. Jeśli zostanie wygenerowana jakakolwiek regularna odpowiedź, ponowna próba nie zostanie wykonana. Bez użycia status_forcelist nawet odpowiedź ze statusem 500 nie będzie ponawiana.
Aby działał w sposób bardziej intuicyjny w pracy ze zdalnym interfejsem API lub serwerem WWW, użyłbym powyższego fragmentu kodu, który wymusza ponawianie prób w stanach 500 , 502 , 503 i 504 , z których wszystkie nie są rzadkie w sieć i (ewentualnie) możliwe do odzyskania, biorąc pod uwagę wystarczająco duży okres wycofania.
EDYCJA : Importuj
Retry
klasę bezpośrednio z urllib3 .źródło
Uważaj, odpowiedź Martijna Pietersa nie jest odpowiednia dla wersji 1.2.1+. Nie można ustawić go globalnie bez łatania biblioteki.
Możesz to zrobić zamiast tego:
źródło
Po trudnych chwilach z niektórymi odpowiedziami tutaj znalazłem bibliotekę o nazwie backoff, która działała lepiej w mojej sytuacji. Podstawowy przykład:
Nadal zalecałbym przetestowanie natywnej funkcjonalności biblioteki, ale jeśli napotkasz jakiekolwiek problemy lub potrzebujesz szerszej kontroli, wycofanie jest opcją.
źródło
requests
, więc działa idealnie!Bardziej czystym sposobem na uzyskanie większej kontroli może być spakowanie elementów ponownej próby do funkcji i uczynienie tej funkcji możliwą do odzyskania za pomocą dekoratora i umieszczenie wyjątków na białej liście.
Stworzyłem to samo tutaj: http://www.praddy.in/retry-decorator-whitelisted-exceptions/
Odtwarzanie kodu w tym linku:
źródło