Skip to content Skip to sidebar Skip to footer

Cannot Import Geopandas With Pyinstaller Executable - Despite Running Fine In The Virtual Env

When my Python application frozen with PyInstaller attempts to import Geopandas, it stops working. Windows 10 PyInstaller 3.3.1 Geopandas 0.4 Here is the source code: print('Hel

Solution 1:

I received this same error and solved it differently to aorr above.

The error was caused because the geopandas datasets included in the package aren't found by pyinstaller because they are .shp files.

I don't use the geopandas datasets in my project/s so instead of manually including them in my .spec file I just commented out the import geopandas.datasets statement from: File "site-packages\geopandas\__init__.py", line 9, in <module>.

This compiled properly and gave me the expected outputs for my program.

Solution 2:

looks like geopandas is aggressively loading their data directory on init. It contains non-python files that are ignored by pyinstaller in your package, so for geopandas to find them when you load it, they must be packaged explicitly.

The "manual" process took me a while to figure out, and I'm using conda as my package manager (if you're not, these edits should still help you). To get this working we need to modify the .spec file that was built when you ran pyinstaller the first time:

# -*- mode: python -*-import os
from PyInstaller.utils.hooks import collect_data_files # this is very helpful
env_path = os.environ['CONDA_PREFIX']
dlls = os.path.join(env_path, 'DLLs')
bins = os.path.join(env_path, 'Library', 'bin')

paths = [
    os.getcwd(),
    env_path,
    dlls,
    bins,
]

# these binary paths might be different on your installation. # modify as needed. # caveat emptor
binaries = [
    (os.path.join(bins,'geos.dll'), ''),
    (os.path.join(bins,'geos_c.dll'), ''),
    (os.path.join(bins,'spatialindex_c-64.dll'), ''),
    (os.path.join(bins,'spatialindex-64.dll'),''),
]

hidden_imports = [
    'ctypes',
    'ctypes.util',
    'fiona',
    'gdal',
    'geos',
    'shapely',
    'shapely.geometry',
    'pyproj',
    'rtree',
    'geopandas.datasets',
    'pytest',
    'pandas._libs.tslibs.timedeltas',
]

# other fancy pyinstaller stuff...

a = Analysis(['run_it.py'],
         pathex=paths, # add all your paths
         binaries=binaries, # add the dlls you may need
         datas=collect_data_files('geopandas', subdir='datasets'), #this is the important bit for your particular error message
         hiddenimports=hidden_imports, # double tap
         hookspath=[],
         runtime_hooks=[],
         excludes=excludes,
         win_no_prefer_redirects=False,
         win_private_assemblies=False,
         cipher=block_cipher)
# remaining fancy pyinstaller stuff...

That should collect your missing data directory and put it where your executable can find it.

The "auto" way would be to build a hook-geopandas.py file that does this for you. pyinstaller loads these hooks when you build as a way of saving and sharing these tricks. In fact, there's already a very nice hook file for shapely, one of geopandas dependencies, that you can review here.

------EDIT--------

I am also currently building a project that depends on geopandas and I realized that the fix above is incomplete as of this date (2018-08-23) because of this issue.

In my run_it.py i have included the following test to ensure fiona and gdal are all packaged up correctly into the bundle:

from osgeo import gdal, ogr, osr
from fiona.ogrextimportIterator, ItemsIterator, KeysIteratorfrom geopandas importGeoDataFrame

This test will probably fail for you unless you're a wizard. This shim worked for me in my .spec file:

_osgeo_pyds = collect_data_files('osgeo', include_py_files=True)

osgeo_pyds = []
for p, lib in _osgeo_pyds:
    if '.pyd' in p:
        osgeo_pyds.append((p, ''))

binaries = osgeo_pyds + [
    # your other binaries
]

a = Analysis(
    # include your kwargs
)

I hope this helps make this answer more complete, and your bundled app do it's geospatial things as expected.

Post a Comment for "Cannot Import Geopandas With Pyinstaller Executable - Despite Running Fine In The Virtual Env"