4

In my python script, I use the requests module to call an API to GET and POST data.

Python environment: anaconda3, python 3.7 / packages: requests 2.24.0, pyinstaller 3.6, openssl 1.1.1h...

I have the following problem with the EXE-file generated by PyInstaller: When I run this file, I get the following error message. This error doesn't occur when I run my script from Python:

Traceback (most recent call last):
  File "site-packages\PyInstaller\loader\rthooks\pyi_rth_certifi.py", line 13, in <module>
  File "c:\programdata\anaconda3\envs\...\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 623, in exec_module
  File "ssl.py", line 98, in <module>
ImportError: DLL load failed: The specified module could not be found.
[20188] Failed to execute script pyi_rth_certifi

If I follow to the excepted error lines (ssl.py):

import _ssl             # if we can't import it, let the error propagate

Why can't ssl be imported?

I searched a long time in serveral post on SO but all these answers didn't help, ex.:

Python Requests throwing SSLError

Python Requests - How to use system ca-certificates (debian/ubuntu)?

Twilio Python Module Errors After Compiling

Fixing SSL certificate error in exe compiled with py2exe (or PyInstaller)

Does anyone have an idea how to fix this? If you need more informations, please write a comment. THX


EDIT: (for Mooncrater's comment)

added Screenshot from python console, entered:

import _ssl

import _ssl


EDIT 2:

Tested "FIX" from SO Question: Python SSL Import Error in PyInstaller generated executable

-> this didn't fix my problem


EDIT 3: Answer by cbolwerk

THX for your answer, this works!

Python 3.7 anaconda environment - import _ssl DLL load fail error

An additional fix is to install the latest OpenSSL Lib, I used 1.1.1h package in my python script, on my PC was installed an older version and that causes the error too.

cbolwerk's answer I tested on a PC where NO OpenSSL is installed and , as I wrote, it works!

droebi
  • 872
  • 1
  • 14
  • 27
  • Are you using a virtual environment with this project? I've had lots of trouble with PyInstaller finding modules that are system-wide installed, but outside of the venv. – Aaron Ciuffo Oct 30 '20 at 10:44
  • @AaronCiuffo thanks for your reply! PyInstaller will run in the same environment, but I'll check anyway. – droebi Oct 30 '20 at 11:32
  • I use venv to set up a base environment, then use pipenv to create a project environment and finally install pyinstaller within each pipenv. It's a bit cumbersome, but tends to work reliably – Aaron Ciuffo Oct 30 '20 at 16:46
  • @AaronCiuffo I did try it, but it did not work... but i won't give up ;) – droebi Oct 30 '20 at 19:06
  • Ummm, can you try the same thing with with Python 3.6? I remember having some issue with Python 3.7 +Pyinstaller. – Mooncrater Nov 02 '20 at 05:02
  • 1
    @Mooncrater I try an older python version, same problem! – droebi Nov 02 '20 at 06:18
  • Hmmm okay. Does `import _ssl` work on a normal python file? – Mooncrater Nov 02 '20 at 06:34
  • @Mooncrater what do you mean with "work on a normal python file"? thx – droebi Nov 02 '20 at 09:29
  • Like enter the python shell in cmd, and then try `import _ssl`. If there is a problem in import, then an exception must be thrown here. – Mooncrater Nov 02 '20 at 09:49
  • @Mooncrater added a screenshot from python console command: >>> import _ssl - nothing happened – droebi Nov 02 '20 at 09:57
  • So what's happening is the Python that pyinstaller is using can not import `_ssl`. Are you using some virtual environment? – Mooncrater Nov 02 '20 at 10:35
  • @Mooncrater as I wrote in my question: when I run the PyInstaller generated EXE file, I get the error message. When I run my script from python, the error doesn't occur... – droebi Nov 02 '20 at 10:36
  • 2
    @droebi Can you please also try adding `--hidden-import pyodbc` with Python 3.6.8 ,while creating the EXE? Taken from [this](https://stackoverflow.com/a/57258734/5345646) answer. I too had a similar problem before. – Mooncrater Nov 02 '20 at 10:39
  • 1
    @Mooncrater i tried this fix, same problem :( ... But thank you very much for your support so far – droebi Nov 02 '20 at 10:47
  • 1
    Hmmm that is pretty weird. I am stuck with Python 3.6.8 + Pyinstaller combo for this reason particularly, I think. Maybe you should raise an issue on pyinstaller's repo page too. That might lead to something. – Mooncrater Nov 02 '20 at 11:00
  • 1
    @Mooncrater yes, weird is the correct word for this... – droebi Nov 02 '20 at 12:52

1 Answers1

5

If you can import ssl in the python within your environment, it means that the ssl module is probably inside your environment. This answer mentions the files you can look for inside your environment. They are either inside your env/Library/bin or env/DLLs. I think you have these installed, but pyinstaller doesn't recognize them. To make sure that pyinstaller knows these files, you can add them to datas. This can be edited in the command when building the .exe file or in the .spec file that is probably created when you have run this command once. This link may be useful there.

In short, add the paths of the DLLs I mentioned to the datas (or binaries inside .spec actually) so that they are recognized by pyinstaller.

So either run the command

pyinstaller --onedir --add-data libcrypto-1_1-x64.dll;. --add-data libssl-1_1-x64.dll;. myscript.py

or change your .spec to something like

datas = [('/path/to/libcrypto-1_1-x64.dll', '.'), ('/path/to/libssl-1_1-x64.dll', '.'),
          (...) ]
...
a = Analysis(...,
             datas=datas,
             ...)
...

and then run

pyinstaller --onedir myscript.spec

This fixed DLL issues for me at least.

cbolwerk
  • 400
  • 1
  • 8