Python 3 flask install wkhtmltopdf on heroku
Asked Answered
Y

2

8

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")
Yance answered 9/10, 2018 at 12:37 Comment(2)
I will keep this in mind, but I had it working on heroku and actually it was not that hard to setup.Yance
Are you sold on wkhtmltopdf? What about weasyprint?Fitts
Y
3

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.

Yance answered 22/10, 2018 at 7:27 Comment(2)
Where to put this command? And what was the purpose of this? I used pdfkit in my django project. Should I update / put this code in any of my filesPlumber
OSError: wkhtmltoimage exited with non-zero code 134. error: - qt.qpa.plugin: Could not find the Qt platform plugin "offscreen" in ""Cantle
S
4

The best approach to get installed wkhtmltopdf on Heroku by getting the binary of wkhtmltopdf for python 3 instead of wkhtmltopdf-pack and you can achieve this by using pydf.

You can install it simply using pip like:

pip install python-pdf

or for Python 2:

pip install python-pdf==0.30.0

Unlike the buildpack based approach pydf installs with the wkhtmltopdf binary included making it very easy to use, and this is the right approach for Heroku.

But if you still want to stick with build-pack wkhtmltopdf, here's another solution you can give it a try:

Via: CLI Installation

$ heroku create --buildpack https://github.com/homelight/wkhtmltox-buildpack.git

Or Manually:

Add the following line to your .buildpacks file

https://github.com/homelight/wkhtmltox-buildpack.git

Please note that this buildpack is only compatible with the cedar-14 stack. You can use heroku stack:set cedar-14 to set the correct stack.

Sharonsharona answered 19/10, 2018 at 6:54 Comment(1)
I have found a solution following my first approach. I was not able to make buildpacks work. I haven't tried this solution.Yance
Y
3

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.

Yance answered 22/10, 2018 at 7:27 Comment(2)
Where to put this command? And what was the purpose of this? I used pdfkit in my django project. Should I update / put this code in any of my filesPlumber
OSError: wkhtmltoimage exited with non-zero code 134. error: - qt.qpa.plugin: Could not find the Qt platform plugin "offscreen" in ""Cantle

© 2022 - 2024 — McMap. All rights reserved.