AWS Lambda не импортирует LXML
Я пытаюсь использовать модуль LXML в AWS Lambda и не везет. Я загрузил LXML, используя следующую команду:
pip install lxml -t folder
чтобы загрузить его в пакет развертывания моей лямбда-функции. Я застегнул содержимое моей лямбда-функции, как и со всеми другими лямбда-функциями, и загрузил его в AWS Lambda.
однако независимо от того, что я пытаюсь, я получаю эту ошибку при запуске функции:
Unable to import module 'handler': /var/task/lxml/etree.so: undefined symbol: PyFPE_jbuf
когда я запустить его локально, у меня нет проблемы, это просто, когда я сталкиваюсь с лямбда, где возникает эта проблема.
4 ответов
я столкнулся с той же проблемой.
ссылка опубликована Рафаэль Брод было полезно, и так было это: https://nervous.io/python/aws/lambda/2016/02/17/scipy-pandas-lambda/
используя две ссылки, я смог успешно импортировать lxml и другие необходимые пакеты. Вот шаги, которым я следовал:
- запустите машину ec2 с Amazon Linux ami
-
запустите следующий скрипт для накопления зависимости:
set -e -o pipefail sudo yum -y upgrade sudo yum -y install gcc python-devel libxml2-devel libxslt-devel virtualenv ~/env && cd ~/env && source bin/activate pip install lxml for dir in lib64/python2.7/site-packages \ lib/python2.7/site-packages do if [ -d $dir ] ; then pushd $dir; zip -r ~/deps.zip .; popd fi done mkdir -p local/lib cp /usr/lib64/ #list of required .so files local/lib/ zip -r ~/deps.zip local/lib
создайте обработчик и рабочие файлы, как указано в ссылке. Пример содержимого файла:
handler.py
import os
import subprocess
libdir = os.path.join(os.getcwd(), 'local', 'lib')
def handler(event, context):
command = 'LD_LIBRARY_PATH={} python worker.py '.format(libdir)
output = subprocess.check_output(command, shell=True)
print output
return
worker.py:
import lxml
def sample_function( input_string = None):
return "lxml import successful!"
if __name__ == "__main__":
result = sample_function()
print result
- добавить обработчик и рабочий в zip-файл.
вот как выглядит структура zip-файла после вышеуказанных шагов:
deps
├── handler.py
├── worker.py
├── local
│ └── lib
│ ├── libanl.so
│ ├── libBrokenLocale.so
| ....
├── lxml
│ ├── builder.py
│ ├── builder.pyc
| ....
├── <other python packages>
- убедитесь, что вы указали правильное имя обработчика при создании лямбда-функции. В приведенном выше примере, это будет- "обработчик.обработчик"
надеюсь, что это помогает!
расширяя эти ответы, я обнаружил, что следующее работает хорошо.
здесь punchline имеет компиляцию lxml python со статическими либами и установку в текущем каталоге, а не в пакетах сайта.
это также означает, что вы можете написать свой код python, как обычно, без необходимости отдельного worker.py или возиться с LD_LIBRARY_PATH
sudo yum groupinstall 'Development Tools'
sudo yum -y install python36-devel python36-pip
sudo ln -s /usr/bin/pip-3.6 /usr/bin/pip3
mkdir lambda && cd lambda
STATIC_DEPS=true pip3 install -t . lxml
zip -r ~/deps.zip *
чтобы перейти на следующий уровень, используйте serverless и docker для обработки всего. здесь в блоге демонстрация этого: https://serverless.com/blog/serverless-python-packaging/
AWS Lambda использует специальную версию Linux (насколько я вижу).
использование "pip install a_package-t folder" является хорошей вещью, чтобы сделать обычно, так как это поможет упаковать ваши зависимости в архиве, который будет отправлен в лямбда, но библиотеки, и особенно двоичные библиотеки должны быть совместимы с версией ОС и Python на лямбда.
вы можете использовать модуль xml, включенный в Python : https://docs.python.org/2/library/xml.etree.elementtree.html
Если вам действительно нужен lxml, эта ссылка дает некоторые рекомендации по компиляции общих библиотек для Lambda : http://www.perrygeo.com/running-python-with-compiled-code-on-aws-lambda.html
немного расширяя ответ маски. В случае установки lxml в частности, библиотеки libxslt и libxml2 уже установлены на AMI, который выполняет AWS lambda. Поэтому нет необходимости запускать подпроцесс с другим LD_LIBRARY_PATH, как в этом ответе, однако необходимо запустить pip install lxml на образе AMI (возможно, также можно скомпилировать, но я не знаю, как).
Launch an ec2 machine with Amazon Linux ami
Run the following script to accumulate dependencies:
set -e -o pipefail
sudo yum -y upgrade
sudo yum -y install gcc python-devel libxml2-devel libxslt-devel
virtualenv ~/env && cd ~/env && source bin/activate
pip install lxml
for dir in lib64/python2.7/site-packages \
lib/python2.7/site-packages
do
if [ -d $dir ] ; then
pushd $dir; zip -r ~/deps.zip .; popd
fi
done
обратите внимание, что последний steps from Marks answer is left out. Вы можете использовать lxml прямо из файла python, содержащего метод обработчика.