AWS Lambda内でLXMLモジュールを使用しようとしていますが、うまくいきません。次のコマンドを使用してLXMLをダウンロードしました。
pip install lxml -t folder
ラムダ関数デプロイメントパッケージにダウンロードします。他のすべてのラムダ関数と同じようにラムダ関数のコンテンツを圧縮し、AWSLambdaにアップロードしました。
ただし、何を試しても、関数を実行すると次のエラーが発生します。
Unable to import module 'handler': /var/task/lxml/etree.so: undefined symbol: PyFPE_jbuf
ローカルで実行しても問題はありません。この問題が発生するのは、Lambdaで実行したときだけです。
私は同じ問題に直面しました。
RaphaëlBraud によって投稿されたリンクは役に立ちました。これも役に立ちました: https://nervous.io/python/aws/lambda/2016/02/17/scipy-pandas-lambda /
2つのリンクを使用して、lxmlおよびその他の必要なパッケージを正常にインポートできました。これが私が従ったステップです:
次のスクリプトを実行して、依存関係を蓄積します。
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
link で指定されているようにハンドラーファイルとワーカーファイルを作成します。サンプルファイルの内容:
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ファイルの構造は次のようになります。
deps
├── handler.py
├── worker.py
├── local
│ └── lib
│ ├── libanl.so
│ ├── libBrokenLocale.so
| ....
├── lxml
│ ├── builder.py
│ ├── builder.pyc
| ....
├── <other python packages>
お役に立てれば!
これらの答えを拡張すると、次のことがうまく機能することがわかりました。
ここでのオチは、静的ライブラリを使用してlxmlをpythonコンパイルし、サイトパッケージではなく現在のディレクトリにインストールすることです。
また、個別のworker.pyを必要とせず、LD_LIBRARY_PATHをいじることなく、通常どおりpythonコードを記述できることも意味します。
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 *
それを次のレベルに引き上げるには、サーバーレスとDockerを使用してすべてを処理します。これを示すブログ投稿は次のとおりです: https://serverless.com/blog/serverless-python-packaging/
マスクの答えを少し拡張します。特にlxmlをインストールする場合、libxsltおよびlibxml2ライブラリはAWSラムダを実行するAMIにすでにインストールされています。したがって、サブプロセスを開始する必要はありません。その回答のように異なるLD_LIBRARY_PATHただし、AMIイメージでpip install lxmlを実行する必要があります(クロスコンパイルも可能かもしれませんが、方法がわかりません)。
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
マークスの回答の最後のステップは省略されていることに注意してください。 lxmlは、ハンドラーメソッドを含むpythonファイルから直接使用できます。
AWS LambdaはLinuxの特別なバージョンを使用しています(私が見る限り)。
「pipinstalla_package -t folder」を使用すると、Lambdaに送信されるアーカイブ内に依存関係をパッケージ化するのに役立つため、通常は適切ですが、ライブラリ、特にバイナリライブラリはバージョンと互換性がある必要がありますOSとラムダのPython。
Python: https://docs.python.org/2/library/xml.etree.elementtree.html に含まれているxmlモジュールを使用できます
本当にlxmlが必要な場合、このリンクはLambdaの共有ライブラリをコンパイルする方法に関するいくつかのトリックを提供します: http://www.perrygeo.com/running-python-with-compiled-code-on-aws-lambda。 html
serverless フレームワークとその組み込みのDocker機能を使用してこれを解決しました。
要件:.awsフォルダーにアクセス可能なAWSプロファイルがあります。
まず、説明されているようにサーバーレスフレームワークをインストールします ここ 。次に、コマンドserverless create --template aws-python3 --name my-lambda
を使用して構成ファイルを作成できます。単純な「hello」関数を使用してserverless.ymlファイルとhandler.pyを作成します。それがsls deploy
で機能するかどうかを確認できます。それが機能する場合は、サーバーレスを使用する準備ができています。
次に、バンドルPython要件。sls plugin install --name serverless-python-requirements
からインストールできます。 "serverless-python-requirements" という名前の追加のプラグインが必要です。
このプラグインは、不足しているlxmlパッケージを解決するために必要なすべての魔法が発生する場所です。 custom-> pythonRequirementsセクションで、dockerizePip: non-linux
プロパティを追加するだけです。 serverless.ymlファイルは次のようになります。
service: producthunt-crawler
provider:
name: aws
runtime: python3.8
functions:
hello:
# some handler that imports lxml
handler: handler.hello
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
fileName: requirements.txt
dockerizePip: non-linux
# Omits tests, __pycache__, *.pyc etc from dependencies
slim: true
これにより、事前設定されたDockerコンテナ内でpython要件のバンドルが実行されます。その後、sls deploy
を実行して魔法が発生することを確認し、次にsls invoke -f my_function
を実行して確認できます。それが機能すること。
サーバーレスを使用して後でdockerizePip: non-linux
オプションをデプロイおよび追加した場合は、すでに構築されている要件をsls requirements clean
でクリーンアップしてください。それ以外の場合は、すでに構築されているものを使用します。