Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CERTIFICATE_VERIFY_FAILED when executing OpenExchangeRatesBackend().update_rates() #403

Closed
gaslitbytech opened this issue Apr 27, 2018 · 1 comment

Comments

@gaslitbytech
Copy link

gaslitbytech commented Apr 27, 2018

Is anybody else having issues with rates with 13.2. I'm new to rates, though followed the docs seem to be getting CERTIFICATE_VERIFY_FAILED even though I can get the same api calls to work through requests directly.

python manage.py shell
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct  3 2017, 00:32:08) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from djmoney.contrib.exchange.backends import OpenExchangeRatesBackend
   ...: from djmoney.contrib.exchange.models import get_rate
   ...: from ipdb import set_trace; set_trace()
   ...: OpenExchangeRatesBackend().update_rates()
   ...: 
   ...: 
--Return--
None
> <ipython-input-1-67fb03c4b911>(3)<module>()
      2 from djmoney.contrib.exchange.models import get_rate
----> 3 from ipdb import set_trace; set_trace()
      4 OpenExchangeRatesBackend().update_rates()

ipdb> c
---------------------------------------------------------------------------
SSLError                                  Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py in do_open(self, http_class, req, **http_conn_args)
   1317                 h.request(req.get_method(), req.selector, req.data, headers,
-> 1318                           encode_chunked=req.has_header('Transfer-encoding'))
   1319             except OSError as err: # timeout error

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py in request(self, method, url, body, headers, encode_chunked)
   1238         """Send a complete request to the server."""
-> 1239         self._send_request(method, url, body, headers, encode_chunked)
   1240 

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py in _send_request(self, method, url, body, headers, encode_chunked)
   1284             body = _encode(body, 'body')
-> 1285         self.endheaders(body, encode_chunked=encode_chunked)
   1286 

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py in endheaders(self, message_body, encode_chunked)
   1233             raise CannotSendHeader()
-> 1234         self._send_output(message_body, encode_chunked=encode_chunked)
   1235 

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py in _send_output(self, message_body, encode_chunked)
   1025         del self._buffer[:]
-> 1026         self.send(msg)
   1027 

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py in send(self, data)
    963             if self.auto_open:
--> 964                 self.connect()
    965             else:

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py in connect(self)
   1399             self.sock = self._context.wrap_socket(self.sock,
-> 1400                                                   server_hostname=server_hostname)
   1401             if not self._context.check_hostname and self._check_hostname:

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)
    406                          server_hostname=server_hostname,
--> 407                          _context=self, _session=session)
    408 

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py in __init__(self, sock, keyfile, certfile, server_side, cert_reqs, ssl_version, ca_certs, do_handshake_on_connect, family, type, proto, fileno, suppress_ragged_eofs, npn_protocols, ciphers, server_hostname, _context, _session)
    813                         raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
--> 814                     self.do_handshake()
    815 

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py in do_handshake(self, block)
   1067                 self.settimeout(None)
-> 1068             self._sslobj.do_handshake()
   1069         finally:

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py in do_handshake(self)
    688         """Start the SSL/TLS handshake."""
--> 689         self._sslobj.do_handshake()
    690         if self.context.check_hostname:

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)

During handling of the above exception, another exception occurred:

URLError                                  Traceback (most recent call last)
<ipython-input-1-67fb03c4b911> in <module>()
      2 from djmoney.contrib.exchange.models import get_rate
      3 from ipdb import set_trace; set_trace()
----> 4 OpenExchangeRatesBackend().update_rates()

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/contextlib.py in inner(*args, **kwds)
     50         def inner(*args, **kwds):
     51             with self._recreate_cm():
---> 52                 return func(*args, **kwds)
     53         return inner
     54 

~/Projects/travel_analytics_markii_ws4/venv-36/lib/python3.6/site-packages/djmoney/contrib/exchange/backends/base.py in update_rates(self, base_currency, **kwargs)
     58         Rate.objects.bulk_create([
     59             Rate(currency=currency, value=value, backend=backend)
---> 60             for currency, value in self.get_rates(**params).items()
     61         ])
     62 

~/Projects/travel_analytics_markii_ws4/venv-36/lib/python3.6/site-packages/djmoney/contrib/exchange/backends/base.py in get_rates(self, **params)
     69 
     70     def get_rates(self, **params):
---> 71         response = self.get_response(**params)
     72         return self.parse_json(response)['rates']

~/Projects/travel_analytics_markii_ws4/venv-36/lib/python3.6/site-packages/djmoney/contrib/exchange/backends/base.py in get_response(self, **params)
     39     def get_response(self, **params):
     40         url = self.get_url(**params)
---> 41         response = urlopen(url)
     42         return response.read()
     43 

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    221     else:
    222         opener = _opener
--> 223     return opener.open(url, data, timeout)
    224 
    225 def install_opener(opener):

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py in open(self, fullurl, data, timeout)
    524             req = meth(req)
    525 
--> 526         response = self._open(req, data)
    527 
    528         # post-process response

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py in _open(self, req, data)
    542         protocol = req.type
    543         result = self._call_chain(self.handle_open, protocol, protocol +
--> 544                                   '_open', req)
    545         if result:
    546             return result

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    502         for handler in handlers:
    503             func = getattr(handler, meth_name)
--> 504             result = func(*args)
    505             if result is not None:
    506                 return result

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py in https_open(self, req)
   1359         def https_open(self, req):
   1360             return self.do_open(http.client.HTTPSConnection, req,
-> 1361                 context=self._context, check_hostname=self._check_hostname)
   1362 
   1363         https_request = AbstractHTTPHandler.do_request_

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py in do_open(self, http_class, req, **http_conn_args)
   1318                           encode_chunked=req.has_header('Transfer-encoding'))
   1319             except OSError as err: # timeout error
-> 1320                 raise URLError(err)
   1321             r = h.getresponse()
   1322         except:

URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)>

In settings.py
added 'djmoney.contrib.exchange' to installed apps

And the following 
# EXCHANGE_BACKEND = 'djmoney.contrib.exchange.backends.OpenExchangeRatesBackend'  # Not needed default
OPEN_EXCHANGE_RATES_APP_ID = 'MY_APP_ID'
# OPEN_EXCHANGE_RATES_URL = 'https://openexchangerates.org/api/latest.json'  # Not needed default

I don't have the issue when using requests directly

import requests
r = requests.get('https://openexchangerates.org/api/latest.json?app_id=MY_APP_ID&base=AUD')
r.status_code
r.headers['content-type']
r.encoding
r.text
r.json()

Edit: I just switched the config to use FixerBackend and it worked. So thats what I'll do to get me over this hurdle.

@Stranger6667
Copy link
Collaborator

Hej @tourdownunder !

Sorry for not getting back to you. urllib is not aware of the location of certificate bundles. requests has it through certifi package, the fix for our case could be similar to this:

    def get_response(self, **params):
        url = self.get_url(**params)
        response = urlopen(url, cafile=cafile)  # some path
        return response.read()

@benjaoming what do you think about the issue? Should we add certifi into dependencies and use it here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants