I installed python 3.6 using
brew install python3
and tried to download a file with
six.moves.urllib.request.urlretrieve from an https, but it throws the error
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
In the Python installation (from .pkg), the README indicates that one needs to run the
Install Certificates.command after the installation to
to be able to use certificates.
However, in brew install, this file does not exist and it does not seem to be run.
It seems that, for some reason, Brew has not run the
Install Certificates.command that comes in the Python3 bundle for Mac. The solution to this issue is to run the following script (copied from
Install Certificates.command) after
brew install python3:
# install_certifi.py # # sample script to install or update a set of default Root Certificates # for the ssl module. Uses the certificates provided by the certifi package: # https://pypi.python.org/pypi/certifi import os import os.path import ssl import stat import subprocess import sys STAT_0o775 = ( stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH ) def main(): openssl_dir, openssl_cafile = os.path.split( ssl.get_default_verify_paths().openssl_cafile) print(" -- pip install --upgrade certifi") subprocess.check_call([sys.executable, "-E", "-s", "-m", "pip", "install", "--upgrade", "certifi"]) import certifi # change working directory to the default SSL directory os.chdir(openssl_dir) relpath_to_certifi_cafile = os.path.relpath(certifi.where()) print(" -- removing any existing file or link") try: os.remove(openssl_cafile) except FileNotFoundError: pass print(" -- creating symlink to certifi certificate bundle") os.symlink(relpath_to_certifi_cafile, openssl_cafile) print(" -- setting permissions") os.chmod(openssl_cafile, STAT_0o775) print(" -- update complete") if __name__ == '__main__': main()
My solution for Mac OS X:
1) Upgrade to Python 3.6.5 using the native app Python installer downloaded from the official Python language website https://www.python.org/downloads/
I’ve found that this installer is taking care of updating the links and symlinks for the new Python a lot better than homebrew.
2) Install a new certificate using “./Install Certificates.command” which is in the refreshed Python 3.6 directory
cd “/Applications/Python 3.6/”
sudo “./Install Certificates.command”
For temporary, following will disable the ssl checking,
import ssl ssl._create_default_https_context = ssl._create_unverified_context
python -c 'import ssl; print(ssl.get_default_verify_paths().openssl_cafile)'
sudo mkdir -p /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/certs
python -c 'import certifi; print(certifi.where())'
sudo cp /usr/local/lib/python3.7/site-packages/certifi/cacert.pem /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/certs/cert.pem
If you need to make your local root certificate (e.g.
local_RootCA.crt) become trusted by python, you can add it into the end of
cat local_RootCA.crt >> `python -c 'import certifi; print(certifi.where())'`
That solution works good for macos brew python 3 installation as well.
positionning SSL_CERT_FILE env var to your ca file also works and it is not invasive.