Search code examples
pythonpython-3.xherokuwkhtmltopdf

Python 3 flask install wkhtmltopdf on heroku


I have a problem to install the wkhtmltopdf binary on my heroku python app (flask).

A year ago (python 2) I already had an issue, but I was able to solve it by first adding the wkhtmltopdf-pack to the requirements and installing it on heroku and then setting the config var to WKHTMLTOPDF_BINARY=wkhtmltopdf-pack. Here is my old thread

Problem now:

I am trying to use the same approach for python 3, but no version of the wkhtmltopdf-pack works, every push gets rejected and I cant install it.

I tried these versions in the requirements:

wkhtmltopdf-pack==0.12.5

wkhtmltopdf-pack==0.12.4

wkhtmltopdf-pack==0.12.3

wkhtmltopdf-pack==0.12.3.0.post1

wkhtmltopdf-pack==0.12.2.4

I get these errors:

No matching distribution

or

error: can't copy 'bin/wkhtmltopdf-pack': doesn't exist or not a regular file

and I remember once it told me there was a SyntaxError and it could not decode something.

Alternative approach:

It seems it is also possible to use a buildpack, so I tried adding a buildpack:

heroku buildpacks:add https://github.com/dscout/wkhtmltopdf-buildpack.git

I see that the buildpack has been added, but there was no installation and there is also no config var for wkhtmltopdf. I dont understand how to trigger the installation, in all documantations for buildpacks its written "add the buildpack and you are ready to go".

Trying to create a PDF gives me a server error here:

OSError: No wkhtmltopdf executable found: "b''"

EDIT:

I managed to install the buildpack:

enter image description here

The push was successful, but no config var has been created and I have no clue what the path to the binary is.

EDIT

I was able to find the files through heroku bash:

app bin dev etc lib lib64 lost+found proc sbin sys tmp usr var

/ $ cd app
~ $ cd vendor
~/vendor $ dir
wkhtmltox
~/vendor $ cd wkhtmltox
~/vendor/wkhtmltox $ dir
lib
~/vendor/wkhtmltox $ cd lib
~/vendor/wkhtmltox/lib $ dir
libwkhtmltox.so  libwkhtmltox.so.0  libwkhtmltox.so.0.12  libwkhtmltox.so.0.12.3
~/vendor/wkhtmltox/lib $ exit

Now I tried to all these files but all give an error:

OSError: wkhtmltopdf exited with non-zero code -11. error

Here is how I set the path:

# WKHTMLTOPDF config
if 'DYNO' in os.environ:
    print ('loading wkhtmltopdf path on heroku')
    MYDIR = os.path.dirname(__file__)    
    WKHTMLTOPDF_CMD = os.path.join(MYDIR + "/vendor/wkhtmltox/lib/", "libwkhtmltox.so")
else:
    print ('loading wkhtmltopdf path on localhost')
    MYDIR = os.path.dirname(__file__)    
    WKHTMLTOPDF_CMD = os.path.join(MYDIR + "/static/executables/bin/", "wkhtmltopdf.exe")

Solution

  • I was able to solve the problem on my own, following my first approach.

    I found an other wkhtmltopdf-pack on pypi and added it to my requirements.txt:

    wkhtmltopdf-pack-ng==0.12.3.0
    

    Heroku was able to install this pack.

    After that I added the config var for wkhtmltopdf:

    heroku config:set WKHTMLTOPDF_BINARY=wkhtmltopdf-pack
    

    The installation is now complete. I need to use the correct path now on my app:

    if 'DYNO' in os.environ:
        print ('loading wkhtmltopdf path on heroku')
        WKHTMLTOPDF_CMD = subprocess.Popen(
            ['which', os.environ.get('WKHTMLTOPDF_BINARY', 'wkhtmltopdf-pack')], # Note we default to 'wkhtmltopdf' as the binary name
            stdout=subprocess.PIPE).communicate()[0].strip()
    else:
        print ('loading wkhtmltopdf path on localhost')
        MYDIR = os.path.dirname(__file__)    
        WKHTMLTOPDF_CMD = os.path.join(MYDIR + "/static/executables/bin/", "wkhtmltopdf.exe")
    

    Thats it.