我们有一个接口,允许将请求发送到Web服务器以获取特定数据。
要使用会话准备要发送到服务器的请求,我创建一个HTTPSAdapter
class HTTPSAdapter(HTTPAdapter):
"""HTTPS adapter that uses windows certificate stores"""
def init_poolmanager(
self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs
):
self.poolmanager= PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_context=ssl.create_default_context(),
**pool_kwargs
)
使用此适配器,我创建一个具有指定max_retries的会话:
class SessionWithDefaultSslContext(requests.Session):
def __init__(self, retries, backoff_factor, status_forcelist):
super(SessionWithDefaultSslContext, self).__init__()
retry = Retry(
total=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
)
self.mount('http://', HTTPAdapter(max_retries=retry))
self.mount('https://', HTTPSAdapter(max_retries=retry))
def requests_retry_session(
self,
retries=3,
backoff_factor=0.3,
status_forcelist=(429, 503),
session=None,
):
"""Create a session with retry and backoff
Got from here:
https://www.peterbe.com/plog/best-practice-with-retries-with-requests
@param retries: number of times to retry
@param backoff_factor: scaling factor for exponential backoff
@param status_forcelist: errors to force retry
@param session: the session
@return: session with retry
"""
session = session or SessionWithDefaultSslContext(retries, backoff_factor, status_forcelist)
return session
最后使用以下命令将请求发送到不同的端点:
with self.requests_retry_session() as session:
r = session.post(url,
auth=self.get_credentials(),
json=data,
verify=True)
return r.status_code == requests.codes.created, r.json()
我正在使用用户名和密码对此服务器进行身份验证,并且还添加了环境变量
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
从该接口发出的请求在Windows上工作正常,但在Linux上引发以下错误
requests.exceptions.SSLError: HTTPSConnectionPool(host='url', port=443): Max retries exceeded with url: /rest-api/target_builds/ (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:726)'),))