Forums

OSError: dlopen() failed to load a library: cairo / cairo-2

I'm using WeasyPrint in a web2py application to generate a PDF.

I have a test environment/account on PythonAnywhere and the application works fine. I've created a separate account (for a client) to host the production version.

I'm not using a virtualenv (I know I probably should) but as far as I can tell the two environments are identical with the same packages and dependencies for WeasyPrint installed in both user environments (using pip install --user ...).

I can also successfully run WeasyPrint in a console using:

$ weasyprint http://weasyprint.org ./weasyprint-website.pdf

But when my application runs and tries to call WeasyPrint I get the following error:

OSError: dlopen() failed to load a library: cairo / cairo-2

Thanks in advance for any help!

That's very strange. Worth trying an uninstall + reinstall of weasyprint? Can you share a minimal repro, a few lines of python code that we can use to try and reproduce the problem?

It's failing inside the web2py application on this line:

from weasyprint import HTML, CSS

I can open a bash console and execute the same line without error: I can also run the weasyprint test succesfully using the command:

weasyprint http://weasyprint.org ./weasyprint-website.pdf

Which accounts are you using? That is, what's the test one where it works, and what's the production one where it doesn't? And can I look at their respective files?

Thanks Giles ...

account mjbeller works

account maxcapgroup does not work

Yes - you can look at the files

I created a virtualenv and installed weasyprint there but I'm still getting same error.

I also confirmed that the weasyprint test works in the virtualenv

weasyprint http://weasyprint.org ./weasyprint-website.pdf

Hmm, nothing obvious in the files.

Do you get the same error if you start a Python 2.7 console and try the import from there? It would be worth checking in both accounts.

the import works in a Python 2.7 console on both accounts

it works within the web2py app on mjbeller account

it fails with the dlopen() within the web2py app on maxcapgroup account

I created a virtualenv on maxcapgroup to isolate the environment but I continue to get the error.

Some more information ...

In the web2py app, the error occurs on

import weasyprint  (or 'from weasyprint import HTML, CSS')

and then within the

File "/home/maxcapgroup/.virtualenvs/mcg-prd/local/lib/python2.7/site-packages/cairocffi/__init__.py", line 46, in <module>

cairo = dlopen(ffi, 'cairo', 'cairo-2')

I looked in the module https://github.com/SimonSapin/cairocffi/blob/master/cairocffi/init.py and see that the error probably occurs on line 38:

lib = ffi.dlopen(path)

I'm unable to investigate further. Any thoughts?

Is the sys.path different during the request processing?

It's entirely likely that the sys.path is different between your console and the web app. I can see that the major difference between your 2 accounts is that maxcapgroup uses a virtualenv and mjbeller uses --user installs of weasyprint and the various cairo libraries. Also, the versions of the libraries in the two accounts are different. I think the first step would be to ensure that the various software versions are the same between the accounts.

I had initially created the two environments the same - with the same versions using just --user installs. I've subsequently tried various combinations of (1) upgrading weasyprint from 0.27 to 0.28 and (2) a virtualenv to isolate the problem - without success. I've since deactivated the virtualenv. I also compared the sys.path generated in the console with the sys.path generated by ..._wsgi.py (following https://help.pythonanywhere.com/pages/DebuggingImportError) and only the web2py libraries themselves were different. I've also confirmed that both web2py versions are the same. I've also tried running web2py from the console using "python web2py.py -S myapp -M" and was successfully able to "import weasyprint". I checked sys.path again using python console, running web2py in console, and running the ..._wsgi.py in console. The only difference in the sys.path in the last two was /var/www/ (which does not contain any modules) and ipython modules (which were listed last).

Anything else I should try?

Success!!

I still couldn't find the root cause of the problem but I reset the environment by deleting everything I had installed using 'pip uninstall'

I then just simply did a 'pip install --user weasyprint==0.27' and it works!

This still doesn't explain why I was experiencing different results in the webapp from the console but at least I can move forward.

That's excellent news. It is a bit of a mystery, though.