urschrei / pyzotero

Pyzotero: a Python client for the Zotero API
https://pyzotero.readthedocs.org
Other
908 stars 99 forks source link

SSLError "CERTIFICATE_VERIFY_FAILED" #131

Closed AlexVillarra closed 3 years ago

AlexVillarra commented 3 years ago

Platform: Windows 10 Python version: 3.9.1 (also tried 3.8.6) Pyzotero version: 1.4.21

Problem description

Trying to run the simple script described in Getting started using the user_id, creating a new private key, and using library_type = "user".

from pyzotero import zotero
zot = zotero.Zotero(library_id, 'user', api_key)
items = zot.top(limit=5)`

In powershell using the following command does give me the correct json dictionary with all the items in my library

curl.exe -H "Zotero-API-Version: 3" -H "Zotero-API-Key: MY_ZOTERO_PRIVATEKEY" "https://api.zotero.org/users/MY_ZOTERO_ID/items/top?limit=5&format=json"

Full traceback

If possible, paste the full traceback in a code block below, and fill in the summary

Traceback --------------------------------------------------------------------------- SSLCertVerificationError Traceback (most recent call last) ~\Desktop\Codes\Python\Python39\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw) 698 # Make the request on the httplib connection object. --> 699 httplib_response = self._make_request( 700 conn, ~\Desktop\Codes\Python\Python39\lib\site-packages\urllib3\connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw) 381 try: --> 382 self._validate_conn(conn) 383 except (SocketTimeout, BaseSSLError) as e: ~\Desktop\Codes\Python\Python39\lib\site-packages\urllib3\connectionpool.py in _validate_conn(self, conn) 1009 if not getattr(conn, "sock", None): # AppEngine might not have `.sock` -> 1010 conn.connect() 1011 ~\Desktop\Codes\Python\Python39\lib\site-packages\urllib3\connection.py in connect(self) 410 --> 411 self.sock = ssl_wrap_socket( 412 sock=conn, ~\Desktop\Codes\Python\Python39\lib\site-packages\urllib3\util\ssl_.py in ssl_wrap_socket(sock, keyfile, certfile, cert_reqs, ca_certs, server_hostname, ssl_version, ciphers, ssl_context, ca_cert_dir, key_password, ca_cert_data, tls_in_tls) 427 if send_sni: --> 428 ssl_sock = _ssl_wrap_socket_impl( 429 sock, context, tls_in_tls, server_hostname=server_hostname ~\Desktop\Codes\Python\Python39\lib\site-packages\urllib3\util\ssl_.py in _ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname) 471 if server_hostname: --> 472 return ssl_context.wrap_socket(sock, server_hostname=server_hostname) 473 else: ~\Desktop\Codes\Python\Python39\lib\ssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session) 499 # ctx._wrap_socket() --> 500 return self.sslsocket_class._create( 501 sock=sock, ~\Desktop\Codes\Python\Python39\lib\ssl.py in _create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session) 1039 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets") -> 1040 self.do_handshake() 1041 except (OSError, ValueError): ~\Desktop\Codes\Python\Python39\lib\ssl.py in do_handshake(self, block) 1308 self.settimeout(None) -> 1309 self._sslobj.do_handshake() 1310 finally: SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1123) During handling of the above exception, another exception occurred: MaxRetryError Traceback (most recent call last) ~\Desktop\Codes\Python\Python39\lib\site-packages\requests\adapters.py in send(self, request, stream, timeout, verify, cert, proxies) 438 if not chunked: --> 439 resp = conn.urlopen( 440 method=request.method, ~\Desktop\Codes\Python\Python39\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw) 754 --> 755 retries = retries.increment( 756 method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2] ~\Desktop\Codes\Python\Python39\lib\site-packages\urllib3\util\retry.py in increment(self, method, url, response, error, _pool, _stacktrace) 572 if new_retry.is_exhausted(): --> 573 raise MaxRetryError(_pool, url, error or ResponseError(cause)) 574 MaxRetryError: HTTPSConnectionPool(host='api.zotero.org', port=443): Max retries exceeded with url: /users/myuserID/items?format=json&limit=100 (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1123)'))) During handling of the above exception, another exception occurred: SSLError Traceback (most recent call last) in ----> 1 zot.items() ~\Desktop\Codes\Python\Python39\lib\site-packages\pyzotero\zotero.py in wrapped_f(self, *args, **kwargs) 202 if kwargs: 203 self.add_parameters(**kwargs) --> 204 retrieved = self._retrieve_data(func(self, *args)) 205 # we now always have links in the header response 206 self.links = self._extract_links() ~\Desktop\Codes\Python\Python39\lib\site-packages\pyzotero\zotero.py in _retrieve_data(self, request, params) 430 # ensure that we wait if there's an active backoff 431 self._check_backoff() --> 432 self.request = requests.get( 433 url=full_url, headers=self.default_headers(), params=params 434 ) ~\Desktop\Codes\Python\Python39\lib\site-packages\requests\api.py in get(url, params, **kwargs) 74 75 kwargs.setdefault('allow_redirects', True) ---> 76 return request('get', url, params=params, **kwargs) 77 78 ~\Desktop\Codes\Python\Python39\lib\site-packages\requests\api.py in request(method, url, **kwargs) 59 # cases, and look like a memory leak in others. 60 with sessions.Session() as session: ---> 61 return session.request(method=method, url=url, **kwargs) 62 63 ~\Desktop\Codes\Python\Python39\lib\site-packages\requests\sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json) 540 } 541 send_kwargs.update(settings) --> 542 resp = self.send(prep, **send_kwargs) 543 544 return resp ~\Desktop\Codes\Python\Python39\lib\site-packages\requests\sessions.py in send(self, request, **kwargs) 653 654 # Send the request --> 655 r = adapter.send(request, **kwargs) 656 657 # Total elapsed time of the request (approximately) ~\Desktop\Codes\Python\Python39\lib\site-packages\requests\adapters.py in send(self, request, stream, timeout, verify, cert, proxies) 512 if isinstance(e.reason, _SSLError): 513 # This branch is for urllib3 v1.22 and later. --> 514 raise SSLError(e, request=request) 515 516 raise ConnectionError(e, request=request) SSLError: HTTPSConnectionPool(host='api.zotero.org', port=443): Max retries exceeded with url: /users/myuserID/items?format=json&limit=100 (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1123)')))
urschrei commented 3 years ago

I can't replicate this on macOS using requests 2.25.0. Could you confirm what version of requests is installed?

urschrei commented 3 years ago

You may also be seeing this if you're behind a firewall, or something else is intercepting / MITMing your requests.

AlexVillarra commented 3 years ago

I can't replicate this on macOS using requests 2.25.0. Could you confirm what version of requests is installed?

I have requests version 2.25.1. I have downgraded it to 2.25.0 and sadly I still get the same error message.

You may also be seeing this if you're behind a firewall, or something else is intercepting / MITMing your requests.

I have checked and indeed I think it was a problem linked to the requests not getting through. I have looked a bit and found (explained better here) that by introducing the parameter verify = False in the _retrieve_data method, it works properly and I can now look at the items in my library.

I will try to put up a pull request after I check that introducing this parameter does not break anything else.