-
-
Notifications
You must be signed in to change notification settings - Fork 710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python 3.8 AWS Lambda incompatibility (Amazon Linux 2) #1003
Comments
Digging a bit further, this is happening only in the Python 3.8 AWS Lambda environment because the distributed version of As seen in the WeasyPrint source code, the newer if pango.pango_version() < 13800:
warnings.warn('@font-face support needs Pango >= 1.38')
else:
# No need to try...catch:
# If there's no fontconfig library, cairocffi already crashed the script
# with OSError: dlopen() failed to load a library: cairo / cairo-2
# So let's hope we find the same file as cairo already did ;)
# Same applies to pangocairo requiring pangoft2
fontconfig = dlopen(ffi, 'fontconfig', 'libfontconfig',
'libfontconfig-1.dll',
'libfontconfig.so.1', 'libfontconfig-1.dylib')
pangoft2 = dlopen(ffi, 'pangoft2-1.0', 'libpangoft2-1.0-0',
'libpangoft2-1.0.so', 'libpangoft2-1.0.dylib') So I am stuck, because I need |
Ok, I managed to install the dependencies, I was missing a symbolic link for the
Now I'm getting a
I'm not familiar with Thanks! |
@Wenzil have a look at How can I install a font on AWS lambda?. |
Ok, I managed to get rid of the above Fontconfig error, but sadly still getting segfaults.
|
@Wenzil Now that you have successfully configured Pango, you probably have to install fonts. |
Thanks @Tontyna and @liZe . I tried copied the default fonts from the older Amazon Linux based 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 |
@liZe - if there were no fonts, shouldn't WeasyPrint/weasyprint/fonts.py Lines 268 to 275 in 05a9513
pangocairo seems ok, but pangoft2 library seems to have a/be the problem... |
Probably, you're right. The problem could be that PangoCairo is not built with the FreeType2 support. In this case, We should check that |
Not sure whether avoiding
Which, I suspect, is triggered by Anybody keen enough to setup an AWS Lambda with modified Of course, preventing the segfault would be an enhancement, but as @Wenzil said: He needs |
Of course. The real pseudo-code to test is something like: font_map = pangocairo.pango_cairo_font_map_new_for_font_type(…)
if font_map:
self.font_map = ffi.gc(font_map, gobject.g_object_unref)
pangoft2.pango_fc_font_map_set_config(…)
else:
self.font_map = None Maybe I can create a new branch / PR tested with another font type unsupported on my system. |
You're right. I really think that Pango can't work with FreeType. Linking the FreeType library (as it's done for the other libraries) in the Dockerfile may help. |
Hey everybody, I'm currently stuck at the same point like @Wenzil and get the exact same segfault in my function. Let me know if I can support you with anything to help get this fixed :) |
Hi All, I've managed to make it work---thanks to Wenzil's and previous work. Here you go my files: Dockerfile FROM lambci/lambda:build-python3.7 AS py37
FROM lambci/lambda:build-python3.8
# download libraries
RUN yum install -y yum-utils rpmdevtools
WORKDIR /tmp
RUN yumdownloader --resolve \
expat \
glib2 \
libffi \
libffi-devel \
cairo \
pango && \
rpmdev-extract *rpm
# install libraries and set links
RUN mkdir /opt/lib
WORKDIR /opt/lib
RUN cp -P -R /tmp/*/usr/lib64/* /opt/lib
RUN ln libgobject-2.0.so.0 libgobject-2.0.so && \
ln libcairo.so.2 libcairo.so && \
ln libpango-1.0.so.0 pango-1.0 && \
ln libpangoft2-1.0.so.0 pangoft2-1.0 && \
ln libpangocairo-1.0.so.0 pangocairo-1.0
# copy fonts and set environment variable
COPY --from=py37 /usr/share/fonts/default /opt/fonts/default
COPY --from=py37 /etc/fonts/fonts.conf /opt/fonts/fonts.conf
RUN sed -i s:/usr/share/fonts:/opt/fonts: /opt/fonts/fonts.conf
ENV FONTCONFIG_PATH="/opt/fonts"
# install weasyprint and dependencies
WORKDIR /opt
RUN pipenv install weasyprint
RUN mkdir -p python/lib/python3.8/site-packages
RUN pipenv lock -r > requirements.txt
RUN pip install -r requirements.txt --no-deps -t python/lib/python3.8/site-packages
# remove warning about cairo < 1.15.4
WORKDIR /opt/python/lib/python3.8/site-packages/weasyprint
RUN sed -i.bak '34,40d' document.py
# run test
WORKDIR /opt
ADD test.py .
RUN pipenv run python test.py
# package lambda layer
WORKDIR /opt
RUN zip -r weasyprint-py38x.zip fonts lib python test.py from weasyprint import html
data = """
<!DOCTYPE html>
<html>
<body>
<h1>Hello World</h1>
<p>Just Testing.</p>
</body>
</html>
"""
HTML(string=data).write_pdf("output.pdf") Bash script to generate lambda-layer #!/bin/bash
set -e
PYVER=py38x
docker image build -f Dockerfile-$PYVER -t weasyprint-$PYVER .
docker create -ti --name dummy-$PYVER weasyprint-$PYVER bash
docker cp dummy-$PYVER:/opt/weasyprint-$PYVER.zip .
docker cp dummy-$PYVER:/opt/output.pdf ./output-$PYVER.pdf
docker rm dummy-$PYVER
aws lambda publish-layer-version --layer-name weasyprint-$PYVER --zip-file fileb://weasyprint-$PYVER.zip
Lambda function import json
from weasyprint import HTML
data = """
<!DOCTYPE html>
<html>
<body>
<h1>Hello World</h1>
<p>Just Testing.</p>
</body>
</html>
"""
def lambda_handler(event, context):
HTML(string=data).write_pdf("/tmp/output.pdf")
return {
'statusCode': 200,
'body': json.dumps('Success!')
} Output of my Lambda function
:-D :-D :-D I hope it helps! |
Hi Again, For reference, the lambda-function code below generates the PDF and returns a URL to download the file from S3. (remember to create the right AWS policies/roles; also, I'm setting the memory to 256Mb and Timeout to 1 min 0 sec). EDIT The lambda function fails from time to time with SEGFAULT. lambda function handler Python 3.8 import json
import boto3
from weasyprint import HTML
s3 = boto3.client('s3')
bucket = "testing-weasyprint-output"
def lambda_handler(event, context):
# generate PDF
filekey = event['filekey']
HTML(string=event['data']).write_pdf(f'/tmp/{filekey}')
# upload output to S3
with open(f'/tmp/{filekey}', 'rb') as f:
s3.upload_fileobj(f, bucket, filekey, ExtraArgs={'ContentType': 'application/pdf'})
# get download URL
Params = {'Bucket': bucket, 'Key': filekey}
url = s3.generate_presigned_url(ClientMethod='get_object', Params=Params, ExpiresIn=60)
# results
return {
'statusCode': 200,
'body': json.dumps({'url': url})
} The input to this function is something like this:
There's a problem though as shown below: Problem
From the return link, we get the figure below (very nice!) For future reference: https://gist.github.com/cpmech/b48729ea07e575d678698bb116d1cbba#file-build-weasyprint-python3-8-lambda-layer-md Thanks for this nice tool |
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 FROM lambci/lambda:build-python3.7
# download libraries
RUN yum install -y yum-utils rpmdevtools
WORKDIR /tmp
RUN yumdownloader libffi libffi-devel cairo pango \
&& rpmdev-extract *rpm
# install libraries and set links
RUN mkdir /opt/lib
WORKDIR /opt/lib
RUN cp -P -R /tmp/*/usr/lib64/* /opt/lib
RUN ln libpango-1.0.so.0 pango-1.0
RUN ln libpangocairo-1.0.so.0 pangocairo-1.0
# install weasyprint and dependencies
WORKDIR /opt
RUN pipenv install weasyprint
RUN mkdir -p python/lib/python3.7/site-packages
RUN pipenv lock -r > requirements.txt
RUN pip install -r requirements.txt --no-deps -t python/lib/python3.7/site-packages
# remove warning about cairo < 1.15.4
WORKDIR /opt/python/lib/python3.7/site-packages/weasyprint
RUN sed -i.bak '34,40d' document.py
# run test
WORKDIR /opt
ADD test.py .
RUN pipenv run python test.py
# package lambda layer
WORKDIR /opt
RUN zip -r weasyprint-py37.zip lib python |
Hi @cpmech , |
Sure, here you go. requirements.txt
|
Hi all, thank you so much for providing these instructions and lambda layers to get this running on AWS Lambda. I am having some issues where my lambda always generates an empty pdf. It will all work and it'll say successful, but when I return the PDF it's a PDF of blank pages. Anyone else experiencing this issue? |
@cpmech thanks a lot for your code and effort. was looking for a long time for a good example running weasyprint on lambda. Works like a charm. The only thing: have you tested if custom fonts/webfonts work in your setup? For me fonts are completely ignored. No matter if I use custom otf fonts via css locally/remote. |
Just double checked. The latest yum pango version is 1.28.1. That means no font face support https://github.com/Kozea/WeasyPrint/blob/master/weasyprint/fonts.py#L40-L41 :-/ damn... |
Just found out that if I use it to write pdf and upload it to S3 it works, so I've gone that route, rather than trying to deliver the pdf binary back via the lambda. Just in case anyone else stumbles upon this issue and can't get it to work. Thanks for all the guidelines everyone |
Did anyone find a solution to make WeasyPrint work on AWS Lambda with Python 3.8? |
Has anyone had any luck installing a later version of pango to enable custom font support? |
@gligorkot I assume it would work using Python 3.8 because Lambda is using Amazon Linux 2 for that Python runtime. And it seems like there is a newer version of pango available. But as @cpmech mentioned here #1003 (comment) Weasyprint is currently not working reliable on Python 3.8 |
@mightym I might need to go revisit the Python 3.8 container to check the dependencies and if pango is at the 1.38+ version there. Thanks for the reminder! |
@gligorkot I didn't have time to so far to check that. Would be great if you could ping me when you found something out :-) |
@mightym good news, looks like the Python 3.8 container has a version we could use, maybe one of us in this thread will have some time to get it properly working on 3.8 soon?
|
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. |
Fantastic! I'll check it out. Thanks! |
@kalekseev you ABSOLUTE LEGEND!!! Got it working this morning and it's a beauty! We use serverless to publish our lambda, so I just built the zip, then unzipped in a folder and stuck that as my |
Is anyone interested in adding some documentation about AWS? |
@kalekseev Should we add a chapter in WeasyPrint’s documentation recommending kotify/cloud-print-utils? (PS: I think that the current |
@liZe I don't see any problem with that, we will support weasyprint layer for the foreseeable future
Great, I will review and release update in a couple of days. |
By the way, aws lambda now supports Docker container images up to 10GB |
Hi @kalekseev! At my company, we are also facing this problem.
Do you mean WeasyPrint will be compatible with Amazon Linux 2 in the near future, out of the box? |
It's already compatible but you have to add native dependencies on your own, see my repo for inspiration.
…On Thu, Aug 12, 2021, at 20:19, Ricardo Molina wrote:
Hi @kalekseev <https://github.com/kalekseev>!
At my company, we are also facing this problem.
> @liZe <https://github.com/liZe> I don't see any problem with that, we will support weasyprint layer for the foreseeable future
>
Do you mean WeasyPrint will be compatible with Amazon Linux 2 in the near future, out of the box?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#1003 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AACZVG6D6FJRYJD3LQRFB3TT4P7BFANCNFSM4JWGLCEA>.
--
Konstantin Alekseev
|
The chapter about AWS has been included in documentation, that was the goal of this issue. Feel free to open new issues if you have problems with AWS! |
For anyone facing font rendering issues with kotify's cloud-print-utils lambda layer, you have to set environment variables (which they mention in the README) Environment variables expected by layer:
|
I have said the environment variables as mentioned, and it is working and I am getting a pdf outputted but the font is not right and getting the following error ' Function Logs Any thoughts why? |
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 #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:
And the resulting error:
Now, the problem is I can't find any
pangoft2
distribution for Fedora nor any compilation instructions.Any pointers?
Thanks!
The text was updated successfully, but these errors were encountered: