In order to make the requests library use a custom ssl context, you need to create a custom HTTPAdapter class and override the init_poolmanager method to pass in extra arguments to the base class's implementation.
See sample code here:
from requests import Session
from requests.adapters import HTTPAdapter
import ssl
class CustomHTTPAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
# this creates a default context with secure default settings,
# which enables server certficiate verification using the
# system's default CA certificates
context = ssl.create_default_context()
# alternatively, you could create your own context manually
# but this does NOT enable server certificate verification
# context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
super().init_poolmanager(*args, **kwargs, ssl_context=context)
def main():
client_session = Session()
client_session.mount("https://", CustomHTTPAdapter())
# now you can use the client_session to make requests
# r = client_session.get("https://<web address>/rest/info?f=json")
Answer from Joe Savage on Stack OverflowIn order to make the requests library use a custom ssl context, you need to create a custom HTTPAdapter class and override the init_poolmanager method to pass in extra arguments to the base class's implementation.
See sample code here:
from requests import Session
from requests.adapters import HTTPAdapter
import ssl
class CustomHTTPAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
# this creates a default context with secure default settings,
# which enables server certficiate verification using the
# system's default CA certificates
context = ssl.create_default_context()
# alternatively, you could create your own context manually
# but this does NOT enable server certificate verification
# context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
super().init_poolmanager(*args, **kwargs, ssl_context=context)
def main():
client_session = Session()
client_session.mount("https://", CustomHTTPAdapter())
# now you can use the client_session to make requests
# r = client_session.get("https://<web address>/rest/info?f=json")
Creating an ssl.SSLContext() on its own doesn't enable certificate verification or load CA certificates by default. This is why you're not seeing SSL errors. Using ssl.create_ssl_context() does set verification by default.
So the issue here isn't with SSLContext or certifi, it's with the website's certificate and how you're constructing your SSLContext. Next step would be to look into why the certificate the website is presenting isn't valid.
I solved it using :
requests.post(url,headers=hdr,json={"filterList":[{}]}, cert='myprivate.pem')
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH,cafile='myCA.crt.pem') ctx.load_cert_chain(certfile='myprivate.pem')
load_cert_chain loads the cert and private key for use as client certificate - which would be the cert argument with requests. cafile describes the CA it should use to verify the server certificate - which would be the verify argument for requests. Combined this would result in:
requests.post(..., cert='myprivate.pem', verify='myCA.crt.pem')