I have encountered an error that takes me beyond my de-bugging capabilities. Camelot's usage of Ghostscript seems to have found an executable of wrong architecture.
Steps taken:
brew install Ghostscript
/opt/homebrew/bin
and /opt/homebrew/lib
to appropriate paths (I think?)camelot/camelot/ext/ghostscript/_gsprint.py Line 256
libgs = ctypes.util.find_library("gs")
to
libgs = distutils.spawn.find_executable("gs")
/opt/homebrew/bin/gs
python3.9 -m pip install camelot-py
I should note, the gs
in location /opt/homebrew/bin/gs
appears to be an alias, not sure if that matters, but it stands to reason it would throw an exception. HOWEVER, the next two "finds" conveyed in the error, /opt/homebrew/bin/gs
and /opt/homebrew/Cellar/ghostscript/9.53.3_1/bin/gs
are both proper executables as far as I can tell.
Common sense tells me that if I were using Windows, I'd have a 64-bit vs 32-bit problem... but I am using MacOS, which I am unfamiliar with.
MacOS -- Apple Silicon M1 -- Python 3.9 -- brew installed Ghostscript -- pip installed camelot-py -- attempted via Jupiter notebook
edit -- also should note that Python 2.7 was a base install that came with the MacBook and its suggested that it not be removed. which python
or python -- version
returns the 2.7 version, not the 3.9 version I run.
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/camelot/ext/ghostscript/_gsprint.py in <module>
259 try:
--> 260 libgs = cdll.LoadLibrary("libgs.so")
261 except OSError:
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ctypes/__init__.py in LoadLibrary(self, name)
451 def LoadLibrary(self, name):
--> 452 return self._dlltype(name)
453
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ctypes/__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error, winmode)
373 if handle is None:
--> 374 self._handle = _dlopen(self._name, mode)
375 else:
OSError: dlopen(libgs.so, 6): image not found
During handling of the above exception, another exception occurred:
OSError Traceback (most recent call last)
<ipython-input-4-3a80516ee21f> in <module>
1 file = r"/Users/joe_kiefner/Documents/Projects/Migration Station/Data_Lake/Arkansas/AR_12_10_2020.pdf"
2
----> 3 tables = camelot.read_pdf(file, flavor = 'lattice', pages='5')
4
5 t_df = tables[0].df
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/camelot/io.py in read_pdf(filepath, pages, password, flavor, suppress_stdout, layout_kwargs, **kwargs)
111 p = PDFHandler(filepath, pages=pages, password=password)
112 kwargs = remove_extra(kwargs, flavor=flavor)
--> 113 tables = p.parse(
114 flavor=flavor,
115 suppress_stdout=suppress_stdout,
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/camelot/handlers.py in parse(self, flavor, suppress_stdout, layout_kwargs, **kwargs)
169 parser = Lattice(**kwargs) if flavor == "lattice" else Stream(**kwargs)
170 for p in pages:
--> 171 t = parser.extract_tables(
172 p, suppress_stdout=suppress_stdout, layout_kwargs=layout_kwargs
173 )
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/camelot/parsers/lattice.py in extract_tables(self, filename, suppress_stdout, layout_kwargs)
400 return []
401
--> 402 self._generate_image()
403 self._generate_table_bbox()
404
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/camelot/parsers/lattice.py in _generate_image(self)
209
210 def _generate_image(self):
--> 211 from ..ext.ghostscript import Ghostscript
212
213 self.imagename = "".join([self.rootname, ".png"])
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/camelot/ext/ghostscript/__init__.py in <module>
22 #
23
---> 24 from . import _gsprint as gs
25
26
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/camelot/ext/ghostscript/_gsprint.py in <module>
274 if not libgs:
275 raise RuntimeError("Please make sure that Ghostscript is installed")
--> 276 libgs = cdll.LoadLibrary(libgs)
277
278 del __win32_finddll
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ctypes/__init__.py in LoadLibrary(self, name)
450
451 def LoadLibrary(self, name):
--> 452 return self._dlltype(name)
453
454 __class_getitem__ = classmethod(_types.GenericAlias)
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ctypes/__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error, winmode)
372
373 if handle is None:
--> 374 self._handle = _dlopen(self._name, mode)
375 else:
376 self._handle = handle
OSError: dlopen(/opt/homebrew/bin/gs, 6): no suitable image found. Did find:
/opt/homebrew/bin/gs: mach-o, but wrong architecture
/opt/homebrew/Cellar/ghostscript/9.53.3_1/bin/gs: mach-o, but wrong architecture
I ran into a similar issue, and managed to sort of solve it.
My problem is that I was using an x86 version of Python (through Anaconda). I discovered this by running:
$ file $(which python)
/Users/cscanlin/opt/anaconda3/envs/marvin/bin/python: Mach-O 64-bit executable x86_64
Fixed by installing a new universal Python binary:
$ file /Library/Frameworks/Python.framework/Versions/3.10/bin/python3
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3 (for architecture x86_64): Mach-O 64-bit executable x86_64
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3 (for architecture arm64): Mach-O 64-bit executable arm64
Unfortunately no official support for arm with base Anaconda installs yet.