如何利用requests的Retry适配器实现CustomSession整体请求重试?
问题:如何让CustomSession的完整请求流程(预请求+主请求)在特定状态码下重试?
我定义了一个继承自requests.Session的CustomSession类,它的request方法会先执行一个使用预定义PRELIM_PARAMS的预请求,再执行用户传入参数的主请求。我希望当该方法返回的响应状态码为502、503、504时,重试整个request方法(即同时重试预请求和主请求)。
常规的Retry适配器配置只会重试主请求,无法触发完整流程的重试:
retries = Retry(total=7, backoff_factor=1, status_forcelist=[502, 503, 504], allowed_methods=None) session.mount('http://', HTTPAdapter(max_retries=retries)) session.mount('https://', HTTPAdapter(max_retries=retries))
我想尽量用Retry适配器而非try-except逻辑实现需求,该怎么做?
解决方案:将完整请求逻辑移至
send方法 requests的Retry适配器是作用于send方法(实际发送请求的核心方法)的。如果把预请求+主请求的逻辑封装到send方法中,适配器的重试机制就会触发整个流程的重试,而非仅单个请求。
具体实现代码
import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry # 预请求参数,根据实际需求定义 PRELIM_PARAMS = { 'method': 'GET', 'url': 'https://your-prelim-url.com' } class CustomSession(requests.Session): def send(self, request, **kwargs): # 1. 执行预请求 prelim_req = self.prepare_request(requests.Request(**PRELIM_PARAMS)) prelim_response = super().send(prelim_req, **kwargs) # 可选:如果预请求失败也触发重试,可添加此句 # prelim_response.raise_for_status() # 2. 执行主请求 main_response = super().send(request, **kwargs) return main_response # 配置重试规则 retries = Retry( total=7, backoff_factor=1, status_forcelist=[502, 503, 504], allowed_methods=None # 允许重试所有请求方法 ) # 初始化自定义会话并挂载适配器 session = CustomSession() session.mount('http://', HTTPAdapter(max_retries=retries)) session.mount('https://', HTTPAdapter(max_retries=retries)) # 使用示例 response = session.get('https://your-main-url.com')
逻辑说明
- 核心原理:
requests.Session.request最终会调用send方法发送请求,将预请求和主请求的逻辑移至send后,每次重试都会重新执行整个流程。 - 预请求失败处理:如果需要预请求失败也触发重试,添加
prelim_response.raise_for_status()即可;若仅希望主请求特定状态码触发重试,可移除该行,直接返回预请求错误响应。 - Retry规则保留:原有的Retry配置完全生效,包括重试次数、退避策略、触发重试的状态码范围。
内容的提问来源于stack exchange,提问作者Elis Evans
相关产品推荐
相关产品推荐

