I am using
import requests
requests.post(url='https://foo.com', data={'bar':'baz'})
but I get a request.exceptions.SSLError.
The website has an expired certficate, but I am not sending sensitive data, so it doesn’t matter to me.
I would imagine there is an argument like ‘verifiy=False’ that I could use, but I can’t seem to find it.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
From the documentation:
requestscan also ignore verifying the SSL certificate if you set
verifyto False.>>> requests.get('https://kennethreitz.com', verify=False) <Response [200]>
If you’re using a third-party module and want to disable the checks, here’s a context manager that monkey patches requests and changes it so that verify=False is the default and suppresses the warning.
import warnings
import contextlib
import requests
from urllib3.exceptions import InsecureRequestWarning
old_merge_environment_settings = requests.Session.merge_environment_settings
@contextlib.contextmanager
def no_ssl_verification():
opened_adapters = set()
def merge_environment_settings(self, url, proxies, stream, verify, cert):
# Verification happens only once per connection so we need to close
# all the opened adapters once we're done. Otherwise, the effects of
# verify=False persist beyond the end of this context manager.
opened_adapters.add(self.get_adapter(url))
settings = old_merge_environment_settings(self, url, proxies, stream, verify, cert)
settings['verify'] = False
return settings
requests.Session.merge_environment_settings = merge_environment_settings
try:
with warnings.catch_warnings():
warnings.simplefilter('ignore', InsecureRequestWarning)
yield
finally:
requests.Session.merge_environment_settings = old_merge_environment_settings
for adapter in opened_adapters:
try:
adapter.close()
except:
pass
Here’s how you use it:
with no_ssl_verification():
requests.get('https://wrong.host.badssl.com/')
print('It works')
requests.get('https://wrong.host.badssl.com/', verify=True)
print('Even if you try to force it to')
requests.get('https://wrong.host.badssl.com/', verify=False)
print('It resets back')
session = requests.Session()
session.verify = True
with no_ssl_verification():
session.get('https://wrong.host.badssl.com/', verify=True)
print('Works even here')
try:
requests.get('https://wrong.host.badssl.com/')
except requests.exceptions.SSLError:
print('It breaks')
try:
session.get('https://wrong.host.badssl.com/')
except requests.exceptions.SSLError:
print('It breaks here again')
Note that this code closes all open adapters that handled a patched request once you leave the context manager. This is because requests maintains a per-session connection pool and certificate validation happens only once per connection so unexpected things like this will happen:
>>> import requests
>>> session = requests.Session()
>>> session.get('https://wrong.host.badssl.com/', verify=False)
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:857: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
<Response [200]>
>>> session.get('https://wrong.host.badssl.com/', verify=True)
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:857: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
<Response [200]>
Method 2
Use requests.packages.urllib3.disable_warnings() and verify=False on requests methods.
import requests
from urllib3.exceptions import InsecureRequestWarning
# Suppress only the single warning from urllib3 needed.
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
# Set `verify=False` on `requests.post`.
requests.post(url='https://example.com', data={'bar':'baz'}, verify=False)
Method 3
To add to Blender’s answer, you can disable SSL certificate validation for all requests using Session.verify = False
import requests
session = requests.Session()
session.verify = False
session.post(url='https://example.com', data={'bar':'baz'})
Note that urllib3, (which Requests uses), strongly discourages making unverified HTTPS requests and will raise an InsecureRequestWarning.
Method 4
Also can be done with a environment variable:
export CURL_CA_BUNDLE=""
Method 5
If you want to send exactly post request with verify=False option, fastest way is to use this code:
import requests
requests.api.request('post', url, data={'bar':'baz'}, json=None, verify=False)
Method 6
If you are writing a scraper and really don’t care about the SSL certificate you can set it global:
import ssl ssl._create_default_https_context = ssl._create_unverified_context
DO NOT USE IN PRODUCTION
Method 7
What has worked for me Due verify=False Bug
Due to a bug on session.verify=False that makes urllib* ignore
that when a environment variable (CURL_CA_BUNDLE) is set. So we set it to nothing.
import requests, os
session = requests.Session()
session.verify = False
session.trust_env = False
os.environ['CURL_CA_BUNDLE']="" # or whaever other is interfering with
session.post(url='https://example.com', data={'bar':'baz'})
Not sure I need trust_env
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0