Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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")
like image 395
Roman Avatar asked Oct 09 '18 12:10

Roman


2 Answers

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.

like image 73
Abdul Rehman Avatar answered Sep 21 '22 09:09

Abdul Rehman


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.

like image 33
Roman Avatar answered Sep 20 '22 09:09

Roman