O módulo de pedidos do Python é simples e elegante, mas uma coisa me incomoda. É possível obter um request.exception.ConnectionError com uma mensagem como:
Max retries exceeded with url: ...
Isso implica que as solicitações podem tentar acessar os dados várias vezes. Mas não há uma única menção dessa possibilidade em nenhum lugar dos documentos. Olhando para o código fonte, não encontrei nenhum lugar onde pudesse alterar o valor padrão (presumivelmente 0).
Portanto, é possível definir de alguma forma o número máximo de novas tentativas para solicitações?
python
python-requests
Kirill Zaitsev
fonte
fonte
requests.get(url, max_retries=num_max_retries, dely_between_retries=3))
just.get
ejust.post
no github.com/kootenpv/justRespostas:
É a
urllib3
biblioteca subjacente que faz a nova tentativa. Para definir uma contagem máxima de novas tentativas, use adaptadores de transporte alternativos :O
max_retries
argumento aceita um número inteiro ou umRetry()
objeto ; o último fornece controle refinado sobre que tipos de falhas são tentadas novamente (um valor inteiro é transformado em umaRetry()
instância que lida apenas com falhas de conexão; os erros após a conexão ser feita, por padrão, não são tratados, pois podem levar a efeitos colaterais) .Resposta antiga, anterior à liberação dos pedidos 1.2.1 :
A
requests
biblioteca realmente não torna isso configurável, nem pretende (consulte esta solicitação de recebimento ). Atualmente (solicitações 1.1), a contagem de novas tentativas é definida como 0. Se você realmente deseja configurá-lo para um valor mais alto, precisará configurá-lo globalmente:Essa constante não está documentada; use-o por sua própria conta e risco, pois lançamentos futuros podem mudar a forma como isso é tratado.
Atualização : e isso fez a mudança; na versão 1.2.1, foi adicionada a opção de definir o
max_retries
parâmetro naHTTPAdapter()
classe , para que agora você precise usar adaptadores de transporte alternativos, veja acima. A abordagem de correção de macacos não funciona mais, a menos que você também corrija osHTTPAdapter.__init__()
padrões (muito pouco recomendado).fonte
session.mount('http://', HTTPAdapter(max_retries=10))
isso apenas para todas as conexões http. O mesmo com https funcionará para todas as conexões https.http://
ehttps://
seja o prefixo mínimo a ser usado, consulte a documentação à qual a resposta está vinculada.HTTPAdapter(max_retries=5)
funcionará apenas para determinado cenário. No documento de solicitações ,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.
para forçar a tentativa de qualquer código de status, consulte a resposta de @ datashaman abaixo.Retry()
para alterar quais cenários de falha são tentados novamente.Isso não apenas altera o max_retries, mas também habilita uma estratégia de retirada que faz com que as solicitações para todos os endereços http: // sejam suspensas por um período de tempo antes de tentar novamente (no total 5 vezes):
Conforme a documentação para
Retry
: se o backoff_factor for 0.1 , sleep () ficará suspenso por [0.1s, 0.2s, 0.4s, ...] entre tentativas. Também forçará uma nova tentativa se o código de status retornado for 500 , 502 , 503 ou 504 .Várias outras opções para
Retry
permitir um controle mais granular:MaxRetryError
ou retornar uma resposta com um código de resposta no intervalo 3xx .NB : raise_on_status é relativamente novo e ainda não foi lançado em urllib3 ou solicitações.Oargumento da palavra-chave raise_on_status parece ter entrado na biblioteca padrão no máximo na versão 3.6 do python.Para fazer solicitações novamente em códigos de status HTTP específicos, use status_forcelist . Por exemplo, status_forcelist = [503] tentará novamente o código de status 503 (serviço indisponível).
Por padrão, a nova tentativa é acionada apenas para estas condições:
TimeoutError
HTTPException
gerado (de http.client no Python 3 else activationplib ). Parece haver exceções HTTP de baixo nível, como URL ou protocolo não formado corretamente.SocketError
ProtocolError
Observe que essas são todas as exceções que impedem que uma resposta HTTP regular seja recebida. Se qualquer resposta regular for gerada, nenhuma nova tentativa será feita. Sem usar o status_forcelist , mesmo uma resposta com status 500 não será tentada novamente.
Para que ele se comporte de uma maneira mais intuitiva para trabalhar com uma API ou servidor da Web remoto, eu usaria o snippet de código acima, que força tentativas nos status 500 , 502 , 503 e 504 , os quais não são incomuns no web e (possivelmente) recuperável, devido a um período de retirada suficientemente grande.
EDITADO : Importar
Retry
classe diretamente do urllib3 .fonte
Cuidado, a resposta de Martijn Pieters não é adequada para a versão 1.2.1+. Você não pode configurá-lo globalmente sem corrigir a biblioteca.
Você pode fazer isso:
fonte
Depois de lutar um pouco com algumas das respostas aqui, encontrei uma biblioteca chamada backoff que funcionava melhor para a minha situação. Um exemplo básico:
Eu ainda recomendo dar uma chance à funcionalidade nativa da biblioteca, mas se você tiver algum problema ou precisar de um controle mais amplo, o backoff é uma opção.
fonte
requests
, então isso funciona perfeitamente!Uma maneira mais limpa de obter maior controle pode ser empacotar o material de repetição em uma função e tornar essa função recuperável usando um decorador e colocar as exceções na lista de permissões.
Eu criei o mesmo aqui: http://www.praddy.in/retry-decorator-whitelisted-exceptions/
Reproduzindo o código nesse link:
fonte