REQUESTS_CA_BUNDLE environment variable not respected
matletix opened this issue · comments
Issue Summary
When setting the REQUESTS_CA_BUNDLE environment variable to use a custom CA with the requests
module, twilio doesn't pick it up in its http_client.
Context : my company uses SSL proxying, therefore I need to be able to add my company custom CA for SSL verification. When making simple requests via requests.get()
, it works well by just setting the REQUESTS_CA_BUNDLE environment variable that is picked up by requests
. However, twilio uses the "prepared request flow" of requests
here : https://github.com/twilio/twilio-python/blob/main/twilio/http/http_client.py#L90
As specified in the requests documentation :
When you are using the prepared request flow, keep in mind that it does not take into account the environment. This can cause problems if you are using environment variables to change the behaviour of requests. For example: Self-signed SSL certificates specified in REQUESTS_CA_BUNDLE will not be taken into account. As a result an SSL: CERTIFICATE_VERIFY_FAILED is thrown. You can get around this behaviour by explicitly merging the environment settings into your session:
from requests import Request, Session s = Session() req = Request('GET', url) prepped = s.prepare_request(req) # Merge environment settings into session settings = s.merge_environment_settings(prepped.url, {}, None, None, None) resp = s.send(prepped, **settings) print(resp.status_code)```
Steps to Reproduce
- Set the REQUESTS_CA_BUNDLE environment variable to the path to a necessary custom CA certificate
- Make a request with
requests.get
: the requests picks up the CA in REQUESTS_CA_BUNDLE - Make a request with twilio, for example via
client.messages.create
, the CA in REQUESTS_CA_BUNDLE isn't picked up and a SSL: CERTIFICATE_VERIFY_FAILED exception is raised.
Exception/Log
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lib/python3.8/site-packages/twilio/rest/api/v2010/account/message/__init__.py", line 95, in create
payload = self._version.create(method='POST', uri=self._uri, data=data, )
File "lib/python3.8/site-packages/twilio/base/version.py", line 193, in create
response = self.request(
File "lib/python3.8/site-packages/twilio/base/version.py", line 39, in request
return self.domain.request(
File "lib/python3.8/site-packages/twilio/base/domain.py", line 38, in request
return self.twilio.request(
File "lib/python3.8/site-packages/twilio/rest/__init__.py", line 131, in request
return self.http_client.request(
File "lib/python3.8/site-packages/twilio/http/http_client.py", line 91, in request
response = session.send(
File "lib/python3.8/site-packages/requests/sessions.py", line 645, in send
r = adapter.send(request, **kwargs)
File "lib/python3.8/site-packages/requests/adapters.py", line 517, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='api.twilio.com', port=443): Max retries exceeded with url: [MASQUED] (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)')))
Technical details:
- twilio-python version: 7.8.0
- python version: 3.9
Fixed by #592
Thank you for the PR! We will review it soon.