У меня есть следующий код, выполненный в AWS Lambda
def handler(event, context):
s3 = boto3.resource('s3')
env = Environment(loader=FileSystemLoader(searchpath='templates'), trim_blocks=True, lstrip_blocks=True,
autoescape=select_autoescape(['html', 'xml']))
template = env.get_template('dag.template')
res = template.render(headers=headers, args=args)
with open('/tmp/w.html', 'w+') as fp:
fp.write(res)
config = pdfkit.configuration(wkhtmltopdf='/usr/local/bin/wkhtmltopdf')
pdfkit.from_file('/tmp/w.html', '/tmp/out.pdf', configuration=config, options = {"enable-local-file-access": True})
Приведенный выше код успешно проходит в тесте локального контейнера докеров, но он не работает при выполнении в AWS Lambda с сообщением об ошибке.
START RequestId: 4c1b6640-08c5-4f32-a935-bbd03d946385 Version: $LATEST
[ERROR] OSError: wkhtmltopdf exited with non-zero code 1. error:
QPainter::begin(): Returned false
Exit with code 1, due to unknown error.
Traceback (most recent call last):
File "/var/task/wbr.py", line 62, in handler
pdfkit.from_file('/tmp/wbr.html', '/opt/out.pdf', configuration=config, options = {"enable-local-file-access": True})
File "/var/task/pdfkit/api.py", line 51, in from_file
return r.to_pdf(output_path)
File "/var/task/pdfkit/pdfkit.py", line 201, in to_pdf
self.handle_error(exit_code, stderr)
File "/var/task/pdfkit/pdfkit.py", line 158, in handle_error
raise IOError("wkhtmltopdf exited with non-zero code {0}. error:\n{1}".format(exit_code, error_msg))
END RequestId: 4c1b6640-08c5-4f32-a935-bbd03d946385
REPORT RequestId: 4c1b6640-08c5-4f32-a935-bbd03d946385 Duration: 580.91 ms Billed Duration: 944 ms Memory Size: 2046 MB Max Memory Used: 101 MB Init Duration: 362.31 ms
Моя лямбда-память составляет 2046 МБ, а хранилище — 2046 МБ. Я использую Python3.8
Спасибо
Трудно понять, что делает сторонняя библиотека, но эта строка выглядит подозрительно:
pdfkit.from_file('/tmp/wbr.html', '/opt/out.pdf', configuration=config, options = {"enable-local-file-access": True})
Похоже, что он пытается вывести файл в каталог /opt/
.
AWS Lambda блокирует запись на диск, разрешая запись только в каталог /tmp/
. Если код попытается записать в /opt/out.pdf
, он будет заблокирован. Это может вызвать ошибку, с которой вы столкнулись.
Вам нужно будет отладить библиотеку, чтобы узнать, что она пытается использовать /opt/out.pdf
вместо /tmp/out.pdf
, которые вы указали в своем коде.
Глядя на wkhtmltopdf, 0.12.6, Предупреждение: доступ к файлу заблокирован — переполнение стека, можно указать путь, который он может использовать.
Страница руководства Ubuntu Manpage: wkhtmltoimage - конвертер html в изображение говорит: --allow <path>
: Разрешить загрузку файла или файлов из указанной папки (повторяется) (но это может не помочь.)
Что ты имеешь в виду под "я тоже так пробовал"? Что вы пробовали?
Я попытался изменить создание PDF-файла в /tmp, а не в /opt. В функции Lambda я изменил /opt/out.pdf на /tmp/out.pdf и все равно получил ту же ошибку.
глупая ошибка. Я изменил путь к файлу локально, но протестировал его, не загружая последний образ докера. Изменение пути с /opt на /tmp сработало.
Я тоже пробовал, но получил ту же ошибку