Search code examples
pythonpyinstaller

How do I tell pyinstaller to use python-certifi-win32 with --onefile option


I have a small scirpt which is using the tableau rest api to download data from tableau views. As the script is running in a corporate environment, I have to use SSL. That's where the python-certifi-win32 package comes into play. Installing the package with pip install python-certifi-win32 patches the certifi package to use the local machine certificate store. From the documentation:

This package patches certifi at runtime to also include certificates from the windows certificate store.

This works perfectly fine when I run the script from source, but if I create an executable using pyinstaller (with the --onefile option), the "patch at runtime" does not seem to happen and I get a "local certificate could not be validated" error, which is the same that I got before installing the python-certifi-win32 package.

As I am fairly new to Python, I could not figure out how exactly the python-certifi-win32 package does the "patch at runtime". I already tried with the --hidden-import option but that did not work.

Any suggestion how to tell pyinstaller (or my script) to apply the "python-certifi-win32 magic" when called as executable?


Solution

  • You won't need to mess with hidden imports, but you will need to import the library itself.

    The package loses some of its auto-magic when executing in PyInstaller's runtime setup. Resolving this depends on where you need the winstore certs, but this is what I do to get it working where I need it for requests:

    if sys.platform == 'win32':
        import certifi_win32
        os.environ['REQUESTS_CA_BUNDLE'] = certifi_win32.wincerts.where()
        certifi_win32.generate_pem()
    

    Setting REQUESTS_CA_BUNDLE will point requests to use the store that certifi_win32 creates. the generate_pem function will union the certificate bundle that is shipped with PyInstaller (located in <MEIPASS>\certifi) and the wincert store. The resulting pem file is written to %LOCALAPPDATA%/.certifi/cacert.pem.