0

我正在使用该pandasdmx库并想访问IMF数据源。以下代码产生 SSLError。

from pathlib import Path

import pandasdmx as sdmx

http_proxy = "my/proxy_server/address"
proxies = {
    "http": http_proxy,
    "https": http_proxy,
}
ssl_cert = Path("path/to/my/ssl_certificate")  # .pem file
data_source = "IMF"

src = sdmx.Request(
    data_source,
    proxies=proxies,
    verify=ssl_cert,
    backend="sqlite",
    fast_save=True,
    expire_after=600,
)

flow_msg = src.dataflow()


Traceback (most recent call last):
  File "C:\Users\D292498\AppData\Local\conda\conda\envs\py38\lib\site-packages\IPython\core\interactiveshell.py", line 3331, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-f5bd59ed1595>", line 1, in <module>
    runfile('C:/Users/D292498/.PyCharmCE2019.2/config/scratches/scratch_1.py', wdir='C:/Users/D292498/.PyCharmCE2019.2/config/scratches')
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.2\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.2\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/Users/D292498/.PyCharmCE2019.2/config/scratches/scratch_1.py", line 24, in <module>
    flow_msg = src.dataflow()
  File "C:\Users\D292498\AppData\Local\conda\conda\envs\py38\lib\site-packages\pandasdmx\api.py", line 392, in get
    raise e from None
  File "C:\Users\D292498\AppData\Local\conda\conda\envs\py38\lib\site-packages\pandasdmx\api.py", line 389, in get
    response = self.session.send(req)
  File "C:\Users\D292498\AppData\Local\conda\conda\envs\py38\lib\site-packages\requests_cache\core.py", line 109, in send
    return send_request_and_cache_response()
  File "C:\Users\D292498\AppData\Local\conda\conda\envs\py38\lib\site-packages\requests_cache\core.py", line 97, in send_request_and_cache_response
    response = super(CachedSession, self).send(request, **kwargs)
  File "C:\Users\D292498\AppData\Local\conda\conda\envs\py38\lib\site-packages\requests\sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\D292498\AppData\Local\conda\conda\envs\py38\lib\site-packages\requests\adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='sdmxcentral.imf.org', port=443): Max retries exceeded with url: /ws/public/sdmxapi/rest/dataflow/IMF/latest (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])")))

但是,我可以在浏览器中轻松加载网站/xml 文档https://sdmxcentral.imf.org/ws/public/sdmxapi/rest/dataflow/IMF/latest。此外,使用常规request库似乎工作正常。以下代码产生status code200。

from pathlib import Path

import requests

proxy_url = "my/proxy_server/address"
proxies = {"http": proxy_url, "https": proxy_url}
ssl_cert = Path("path/to/my/ssl_certificate")  # .pem file
web_address = "https://sdmxcentral.imf.org/ws/public/sdmxapi/rest/dataflow/IMF/latest"

r = requests.get(web_address, proxies=proxies, verify=ssl_cert)
print(r.status_code)  # 200 OK
4

2 回答 2

0

显然,sdmx.Request()没有正确转发verify论点。

在2020 年 11 月 20 日的一个问题中——sdmx1一个更积极维护的分支——中,pandaSDMX这个错误被注意到,并在 2020 年 12 月 16 日的 v1.6.0 中得到修复。verify现在很荣幸,因此不再需要在另一个答案中手动添加证书。

于 2021-03-28T14:37:24.557 回答
0

显然,sdmx.Request()没有正确转发verify论点。

因此,对底层request库的调用将使用其标准 CA 证书。因此,我们需要将我们的证书信息添加到该特定文件中。

以下代码行应该可以解决问题:

from pathlib import Path

import certifi

ssl_cert = Path("path/to/my/ssl_certificate")  # .pem file

cafile = certifi.where()

with open(ssl_cert, 'rb') as infile:
    customca = infile.read()

with open(cafile, 'ab') as outfile:
    outfile.write(customca)

请在https://incognitjoe.github.io/adding-certs-to-requests.html找到更多详细信息。

于 2020-05-22T12:02:32.293 回答