I've just finished testing a Python programme which involves logging into a site and requires a CSRF cookie to be set. I've tried packaging it as an exe using py2exe
and got a socket error. I have the same problem when I try with PyInstaller
. Googling the Errno I found a few other people with the same problem and so I know the problem is to do with the location of SLL certificates.
This is my site_agent
class including the logging calls.
class site_agent:
self.get_params()
URL = root_url + '/accounts/login/'
# Retrieve the CSRF token first
self.agent = requests.session()
self.agent.get(URL) # retrieves the cookie # This line throws the error
self.csrftoken = self.agent.cookies['csrftoken']
# Set up login data including the CSRF cookie
login_data = {'username': self.username,
'password': self.password,
'csrfmiddlewaretoken' : self.csrftoken}
# Log in
logging.info('Logging in')
response = self.agent.post(URL, data=login_data, headers=hdr)
The error comes at the self.agent.get(URL)
line and the Traceback shows:
Traceback (most recent call last):
File "<string>", line 223, in <module>
File "<string>", line 198, in main
File "<string>", line 49, in __init__
File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 350, in get
File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 338, in requ
est
File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 441, in send
File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.adapters", line 331, in send
requests.exceptions.SSLError: [Errno 185090050] _ssl.c:336: error:0B084002:x509
certificate routines:X509_load_cert_crl_file:system lib
Does this mean that the problem is in requests.adapters
?
If so, can I just edit it in my installed Python packages to look for cacert.pem somewhere else, rebuild my exe with py2exe
or PyInstaller
, then change it back in my installed version of Python?
EDIT
I now have the programme running after compiling with PyInstaller
and setting verify=False
in all requests.get()
and requests.post()
calls. But SSL is there for a a reason and I'd really like to be able to fix this error before letting anyone use the tool.
This can be solved easily if you are using "requests" module.
1) Place the below code in your main python file where "requests" module is used
os.environ['REQUESTS_CA_BUNDLE'] = "certifi/cacert.pem"
2) Within your distributable folder where exe is present, create a folder called "certifi" and place the "cacert.pem" file within it.
3) You can find the "cacert.pem" file by
pip install certifi
import certifi
certifi.where()
Awesome.. now your distributable includes the necessary certificates to validate ssl calls.
If using pyinstaller... create a hook-requests.py
file in PyInstaller\hooks\
for the requests lib containing
from hookutils import collect_data_files
# Get the cacert.pem
datas = collect_data_files('requests')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With