Doc enhancement: Note dependency on libgs.so (libgs.dylib on Mac) for ghostscript
See original GitHub issueThe Camelot documentation highlights a dependency on Ghostscript and adds a check that confirms that the Ghostscript binary is installed. The key dependency for Camelot to run successfully is on a working copy of the libgs library (libgs.dylib for MacOS).
Specific ask: Would ask that a note be added to the documentation
that in addition to running the gs
binary for version info, add a note that
states you require a full distribution ghostscript that includes the libraries
and fonts.
Details:
I performed the following steps:
- Installed the Camelot python package with no issues
- Installed the conda-forge Ghostscript package with no issues
- Ran the conda-forge gs per the Camelot docs with no issues
Using the conda Ghostscript was a mistake and the Camelot documentation suggests using Homebrew toolchain. But I thought I would be good with using the conda Ghostscript but when ran a test script I got the following error:
>>> import camelot
>>> tables = camelot.read_pdf('foo.pdf')
Traceback (most recent call last):
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/site-packages/camelot/ext/ghostscript/_gsprint.py", line 260, in <module>
libgs = cdll.LoadLibrary("libgs.so")
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/ctypes/__init__.py", line 442, in LoadLibrary
return self._dlltype(name)
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/ctypes/__init__.py", line 364, in __init__
self._handle = _dlopen(self._name, mode)
OSError: dlopen(libgs.so, 6): image not found
Steps to reproduce the behavior:
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/site-packages/camelot/io.py", line 117, in read_pdf
**kwargs
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/site-packages/camelot/handlers.py", line 172, in parse
p, suppress_stdout=suppress_stdout, layout_kwargs=layout_kwargs
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/site-packages/camelot/parsers/lattice.py", line 402, in extract_tables
self._generate_image()
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/site-packages/camelot/parsers/lattice.py", line 211, in _generate_image
from ..ext.ghostscript import Ghostscript
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/site-packages/camelot/ext/ghostscript/__init__.py", line 24, in <module>
from . import _gsprint as gs
File "/Users/jameshall/opt/anaconda3/envs/camelot/lib/python3.7/site-packages/camelot/ext/ghostscript/_gsprint.py", line 267, in <module>
raise RuntimeError("Please make sure that Ghostscript is installed")
RuntimeError: Please make sure that Ghostscript is installed
Looking at the conda package for Ghostscript I determined it only delivered the userland binaries and not the fonts and libraries. I have opened an issue with conda packaging team and asked that the binaries and fonts be delivered.
Workaround: Install Ghostscript using the Homebrew tool chain
Owners of Camelot may argue (rightfully) this is a case of “pilot error / not following the docs”. Just would suggest adding a note might prevent what looks like a common pilot error situation (See here and here. Homebrew dependency is pretty heavy weight lift also (you need Xcode for Homebrew to work, so a lot of stuff to download/configure to get going with Camelot).
Thanks for a great tool!
Environment
- macOS Catalina 10.15.6
- Python version: Python 3.7.9 (default, Aug 31 2020, 07:22:35)
- Ghostscript version: 9.22
- Camelot version: 0.8.2
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (11 by maintainers)
I had this problem today. Solved creating an env in conda installing camelot at the sime time: conda create -n camelot -c conda-forge camelot-py
Sorry I should’ve spent more time reproducing this! You’re correct, installing
ghostscript
fromconda-forge
doesn’t installlibgs
! I was working under the assumption without something to back me up 😦 This test in the camelot conda-forge recipe, to just check ifcamelot
is importable is not enough.camelot
used to do a subprocess call toghostscript
before, and this test should’ve been updated when we started usinglibgs
instead. I’ll look into your PR today and merge it.I’m on Ubuntu 20.04 and I just removed the
ghostscript
package usingapt
.Thank you for looking into
ctypes
and suggesting to look forlibgs
using the code snippet! I was able to findlibgs
:I didn’t remove it after I found it (to reproduce the bug) as that was going to take away
evince
and a lot of other useful packages. 😅You’re correct! I checked the shared library dependencies for
gs
and there are a lot of them:$ ldd /usr/bin/gs
In contrast,
gs
fromconda-forge
has very little dependencies:Their sizes are also in contrast, I’m guessing that
gs
fromconda-forge
is statically linked tolibgs
in one executable:To reproduce the bug in a clean environment, I created a docker container from the latest
ubuntu
image:No
libgs
found! I tried to runcamelot
on the test pdf to reproduce your bug, but ran into a completely new one!Turns out even
opencv
requires a shared library that is not present by default on this base ubuntu imageAfter installing
libgl1-mesa-glx
, I was able to reproduce your bug:And after installing
libgs9
:It all worked fine:
I didn’t quite get this, what do you mean?