The problem you are having is caused by an untrusted SSL certificate.
Like dirk mentioned in a previous comment, the quickest fix is setting verify=False:
requests.get('https://example.com', verify=False)
Please note that this will cause the certificate not to be verified. This will expose your application to security risks, such as man-in-the-middle attacks.
Of course, apply judgment. As mentioned in the comments, this may be acceptable for quick/throwaway applications/scripts, but this should really not go to production software.
If just skipping the certificate check is not acceptable in your particular context, consider the following options, your best option is to set the verify parameter to a string that is the path of the .pem file of the certificate (which you should obtain by some sort of secure means).
So, as of version 2.0, the verify parameter accepts the following values, with their respective semantics:
True: causes the certificate to validated against the library's own trusted certificate authorities (Note: you can see which root certificates (RCs) Requests uses via the Certifi library, a trust database of RCs extracted from Requests: Certifi - Trust Database for Humans).False: bypasses certificate validation completely.Path to a CA_BUNDLE file for Requests to use to validate the certificates.
Source: Requests - SSL Cert Verification
Also take a look at the cert parameter on the same page.
The problem you are having is caused by an untrusted SSL certificate.
Like dirk mentioned in a previous comment, the quickest fix is setting verify=False:
requests.get('https://example.com', verify=False)
Please note that this will cause the certificate not to be verified. This will expose your application to security risks, such as man-in-the-middle attacks.
Of course, apply judgment. As mentioned in the comments, this may be acceptable for quick/throwaway applications/scripts, but this should really not go to production software.
If just skipping the certificate check is not acceptable in your particular context, consider the following options, your best option is to set the verify parameter to a string that is the path of the .pem file of the certificate (which you should obtain by some sort of secure means).
So, as of version 2.0, the verify parameter accepts the following values, with their respective semantics:
True: causes the certificate to validated against the library's own trusted certificate authorities (Note: you can see which root certificates (RCs) Requests uses via the Certifi library, a trust database of RCs extracted from Requests: Certifi - Trust Database for Humans).False: bypasses certificate validation completely.Path to a CA_BUNDLE file for Requests to use to validate the certificates.
Source: Requests - SSL Cert Verification
Also take a look at the cert parameter on the same page.
From Requests' documentation on SSL verification:
Requests can verify SSL certificates for HTTPS requests, just like a web browser. To check a host’s SSL certificate, you can use the verify argument (for example, interactively):
requests.get('https://kennethreitz.com', verify=True)
If you don't want to verify your SSL certificate, make verify=False
macos - Mac OSX python ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749) - Stack Overflow
How to fix ssl.SSLCertVerificationError: … - Apple Community
macos - Python requests throwing SSL errors - Stack Overflow
python - urllib and "SSL: CERTIFICATE_VERIFY_FAILED" Error - Stack Overflow
What does CERTIFICATE_VERIFY_FAILED mean in Python?
Does updating Python fix SSL certificate errors?
Why does Python reject valid SSL certificates?
Videos
When you run the python installer, they display this information to you. It is also documented in /Applications/Python 3.6/ReadMe.rtf, but it's very easily overlooked.
Just browse to Applications/Python 3.6 and double-click Install Certificates.command
There is an issue in the Python bug tracker about this. http://bugs.python.org/issue29480
Update: This issue is marked as resolved in the bug tracker with this text being part of the latest comment:
... For 3.7.0b2, I have tried to make things more obvious in two ways. One, the installer package will now attempt to open a Finder window for the /Application/Python 3.7 folder that contains the "Install Certificates.command". Two, rather than just a generic "installation complete" message at the end of the install, there is now a tailored message that urges the user to click on the "Install Certificates.command" icon. ...
I solved this problem using this command:
open /Applications/Python\ 3.7/Install\ Certificates.command
I have Python 3.7 in my machine.
TL;DR
The remote website seems to be the problem, not Python. There is likely no fix for this other than to fix the website.
Longer Explanation
The website/server your are dealing with is apparently configured incorrectly. This has nothing directly to do with Python. That said, you can ignore any certificate errors with e.g.:
r = requests.get(url=URL, params=PARAMS, verify=False)
or you can otherwise try to point Python at the missing certificates (as pointed out by @dave_thompson_085 in the comments).
However, this is unlikely to do any good as the server then apparently responds with a 500: Internal Server Error (verified with curl) and a Content-Length: 0, which would seem to indicate an error in the processing of api.php itself (i.e. there is no JSON to process anyway).
If you are working within a corporate environment that decrypts your traffic, or possibly proxy servers as part of a VPN, then I have found that the certifi library fails to include the certificate for the decryption server in the certificate package. This leaves you with only 1 good solution, 1 mediocre solution, and 1 bad solution. The bad solution is to not verify the certificates. The mediocre solution is to ask your IT department to whitelist the website you are trying to contact, but you will have to ask them over and over again for every new website you try to contact.
There is a pretty good article on this issue by David Tippet at the following link. https://levelup.gitconnected.com/fixing-your-ssl-verify-errors-in-python-71c2201db4b2
So, what is the good solution? You will have to start by finding someone in your IT department who can give you the URL or IP address for your SSL decryption server, or you can ask them to give you the .pem file in a base64 format for the server. This is a clear text human readable file, and looks something like this:
Certificate example
It will have a 7 lines starting with a comment #, a line that says -----BEGIN CERTIFICATE-----, and a line that ends as -----END CERTIFICATE-----.
Open up your python environment and check to see if you have certifi with the command:
import certifi
Then find out where the chain of certificates is on your computer that Python is using with
certifi.where()
Navigate to the file path returned by certifi.where() and make a copy of that file in case you break something. Mine was located here:
'C:\Users\user_name\Anaconda3\envs\gispy\lib\site-packages\certifi\cacert.pem'
Open up that .txt file and copy and paste the entire certificate for your proxy/decryption server to the end of the cacert.pem file. Now your requests call should work.
This isn't a solution to your specific problem, but I'm putting it here because this thread is the top Google result for "SSL: CERTIFICATE_VERIFY_FAILED", and it lead me on a wild goose chase.
If you have installed Python 3.6 on OSX and are getting the "SSL: CERTIFICATE_VERIFY_FAILED" error when trying to connect to an https:// site, it's probably because Python 3.6 on OSX has no certificates at all, and can't validate any SSL connections. This is a change for 3.6 on OSX, and requires a post-install step, which installs the certifi package of certificates. This is documented in the file ReadMe.rtf, which you can find at /Applications/Python\ 3.6/ReadMe.rtf (see also the file Conclusion.rtf, and the script build-installer.py that generates the macOS installer).
The ReadMe will have you run the post-install script at
/Applications/Python\ 3.10/Install\ Certificates.command (Terminal App, this command alone should, fix the issue. Be sure to update the file path using your current subversion.)
(its source is install_certificates.command), which:
- first installs the Python package
certifi, and - then creates a symbolic link from the OpenSSL certificates file to the certificates file installed by the package
certifi.
Release notes have some more info: https://www.python.org/downloads/release/python-360/
On newer versions of Python, there is more documentation about this:
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/ReadMe.rtf#L22-L34
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/Conclusion.rtf#L15-L19
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/Welcome.rtf#L23-L25
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/install_certificates.command
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/README.rst
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/build-installer.py#L239-L246
If you just want to bypass verification, you can create a new SSLContext. By default newly created contexts use CERT_NONE.
Be careful with this as stated in section 17.3.7.2.1
When calling the SSLContext constructor directly, CERT_NONE is the default. Since it does not authenticate the other peer, it can be insecure, especially in client mode where most of time you would like to ensure the authenticity of the server you’re talking to. Therefore, when in client mode, it is highly recommended to use CERT_REQUIRED.
But if you just want it to work now for some other reason you can do the following, you'll have to import ssl as well:
input = input.replace("!web ", "")
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' })
gcontext = ssl.SSLContext() # Only for gangstars
info = urllib2.urlopen(req, context=gcontext).read()
Message.Chat.SendMessage ("" + info)
This should get round your problem but you're not really solving any of the issues, but you won't see the [SSL: CERTIFICATE_VERIFY_FAILED] because you now aren't verifying the cert!
To add to the above, if you want to know more about why you are seeing these issues you will want to have a look at PEP 476.
This PEP proposes to enable verification of X509 certificate signatures, as well as hostname verification for Python's HTTP clients by default, subject to opt-out on a per-call basis. This change would be applied to Python 2.7, Python 3.4, and Python 3.5.
There is an advised opt out which isn't dissimilar to my advice above:
import ssl
# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)
It also features a highly discouraged option via monkeypatching which you don't often see in python:
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
Which overrides the default function for context creation with the function to create an unverified context.
Please note with this as stated in the PEP:
This guidance is aimed primarily at system administrators that wish to adopt newer versions of Python that implement this PEP in legacy environments that do not yet support certificate verification on HTTPS connections. For example, an administrator may opt out by adding the monkeypatch above to sitecustomize.py in their Standard Operating Environment for Python. Applications and libraries SHOULD NOT be making this change process wide (except perhaps in response to a system administrator controlled configuration setting).
If you want to read a paper on why not validating certs is bad in software you can find it here!
Ive been getting this error while working with the "pytube" module:
An error occurred: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)>
Ive seen similar issues online where the solution was to upgrade certifi with pip. I did that and I still have the issue.
Im on macos 14.2.1 with the m1 chip
For anyone who still wonders on how to fix this, i got mine by installing the "Install Certificates.command"
Here is how I did,

Just double click on that file wait for it to install and in my case, you will be ready to go
Creating a symlink from OS certificates to Python worked for me:
ln -s /etc/ssl/* /Library/Frameworks/Python.framework/Versions/3.9/etc/openssl
(I'm on macOS, using pyenv)