WeasyPrint: Python 3.8 AWS Lambda incompatibility (Amazon Linux 2)
Hello there!
I’m trying to build and package WeasyPrint and its native dependencies into an AWS Lambda layer for the Python 3.8 runtime.
The steps described in https://github.com/Kozea/WeasyPrint/issues/916 work for the Python 3.7 runtime environment (Amazon Linux 1), but fail with Python 3.8.
Here’s as far as I got:
# Dockerfile
FROM lambci/lambda:build-python3.8
# Based on https://aws.amazon.com/premiumsupport/knowledge-center/lambda-linux-binary-package/
RUN yum install -y yum-utils rpmdevtools
WORKDIR /tmp
RUN yumdownloader --resolve \
libffi \
libffi-devel \
cairo \
pango && \
rpmdev-extract *rpm
RUN mkdir /opt/lib
WORKDIR /opt/lib
RUN cp -P -R /tmp/*/usr/lib64/* /opt/lib
RUN ln libcairo.so.2 libcairo.so && \
ln libpango-1.0.so.0 pango-1.0 && \
ln libpangocairo-1.0.so.0 pangocairo-1.0
WORKDIR /opt
RUN pip3 install weasyprint -t python
RUN zip -r /var/task/weasyprint_lambda_layer.zip ./lib ./python
# Test the package
RUN PYTHONPATH=python python -m weasyprint
And the resulting error:
Traceback (most recent call last):
File "/var/lang/lib/python3.8/runpy.py", line 183, in _run_module_as_main
mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
File "/var/lang/lib/python3.8/runpy.py", line 142, in _get_module_details
return _get_module_details(pkg_main_name, error)
File "/var/lang/lib/python3.8/runpy.py", line 109, in _get_module_details
__import__(pkg_name)
File "/opt/python/weasyprint/__init__.py", line 443, in <module>
from .document import Document, Page # noqa isort:skip
File "/opt/python/weasyprint/document.py", line 24, in <module>
from .fonts import FontConfiguration
File "/opt/python/weasyprint/fonts.py", line 54, in <module>
pangoft2 = dlopen(ffi, 'pangoft2-1.0', 'libpangoft2-1.0-0',
File "/opt/python/weasyprint/text.py", line 253, in dlopen
return ffi.dlopen(names[0]) # pragma: no cover
File "/opt/python/cffi/api.py", line 146, in dlopen
lib, function_cache = _make_ffi_library(self, name, flags)
File "/opt/python/cffi/api.py", line 828, in _make_ffi_library
backendlib = _load_backend_lib(backend, libname, flags)
File "/opt/python/cffi/api.py", line 823, in _load_backend_lib
raise OSError(msg)
OSError: cannot load library 'pangoft2-1.0': pangoft2-1.0: cannot open shared object file: No such file or directory. Additionally, ctypes.util.find_library() did not manage to locate a library called 'pangoft2-1.0'
Now, the problem is I can’t find any pangoft2 distribution for Fedora nor any compilation instructions.
Any pointers?
Thanks!
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 39 (14 by maintainers)
Links to this issue
Commits related to this issue
- Use a .so.N file name to find libpangoft2 Related to #1003. — committed to Kozea/WeasyPrint by liZe 3 years ago
Hi, I have open sourced our solution https://github.com/kotify/cloud-print-utils, it builds weasyprint layer for amazon linux 2, here test results of the report sample, feedback would be great.
I believe that problem in @cpmech solution is hard links used to create .so files while that is working solution in general it doesn’t work with zip files, zip doesn’t preserve links so lambda server end up with two different files for the same library and weasyprint loads .so files while the rest of the stack loads .so.N files that leads to memory problems. We fixed that by patching weasyprint https://github.com/kotify/cloud-print-utils/blob/2c64672d0f20d3b4bae85dff5cfd976eb03b5b0f/layers/weasyprint/builder.sh#L9, I’m going to create pull requests with rationale why it’s the right thing to load .so.N files instead of .so.
Another non-trivial thing is to configure pixbuf https://github.com/kotify/cloud-print-utils/blob/2c64672d0f20d3b4bae85dff5cfd976eb03b5b0f/layers/cairo-pixbuf-libffi-pango/builder.sh#L23-L30, otherwise images doesn’t work.
Hi Again, unfortunately, the code DOES SEGFAULT from time to time… So, it’s not working well. Sorry.
So, going back to Python 3.7.
Here you go the Dockefile:
Dockerfile
Sure, here you go.
requirements.txt
Hi All,
I’ve managed to make it work—thanks to Wenzil’s and previous work.
Here you go my files:
Dockerfile
test.py
Bash script to generate lambda-layer
Lambda function
Output of my Lambda function
😄 😄 😄
I hope it helps! And thanks again.
Thanks @Tontyna and @liZe . I tried copied the default fonts from the older Amazon Linux based
lambda:build-python3.7image to the built layer. It got rid of a “No fonts configured” error but still getting the segfaults.I have to put this away for now but I’ll try to get back to it when time permits. If anyone wants to keep digging in the mean time here’s the Dockerfile I currently have:
And I set
FONTCONFIG_PATHto/opt/fonts