ephemというPythonのライブラリをレイヤーにしてAWS Lambdaに登録してある。これを2年ぶりに更新することにしたら前回と同じところで引っかかってしまった。
結論。
AWS LambdaはAmazon Linux上で動いているので、レイヤー用のライブラリやパッケージのインストールはWindows上ではなくcloud9かAmazon Linuxで動いているec2上で実行した方が問題が少ない。
言われてみればそれはそうなのだが、例えばPythonだけで書かれているようなライブラリだとWindows上で作成しても動いてしまうことがあるので忘れがちであった。
ついでに、cloud9で作ってそのままs3にアップロードするのが便利。
レイヤー作成手順としては、pipで任意のディレクトリにパッケージをインストールし、ディレクトリ名をpython(ケースセンシティブ)と変更後zipに圧縮するだけである。
これはなんとなく覚えていたのでレイヤーを更新して実行すると "ImportError: No module named 'ephem._libastro'" というエラーが発生した。
ephem._libastro で検索するとライブラリ作者のgithubが表示される。このページには見覚えがあった(そして前回も解決にさほど役に立たなかったことも)。
前回レイヤーを登録したときも割と苦労したのを思い出したので自分のツイートを検索してみると、
新月と満月の日を算出するのにAWS Lambdaにephemねじ込んだんだけど、なんか他におもしろい計算できないかな
— ロイコ ᛚᛖᚢᚴᛟ (@Leukosaphir) August 28, 2022
としか書いてなくて自分で腹立たしかった。後の自分のためにどうやったのかちゃんと手順を書いておいてほしい。
今回気づいたのは、自分で書いておいた "ephem413: cp39-manylinux_2_17_x86_64" というレイヤーのメモと、
If you have a C compiler and the pip Python installer tool on your system
というephemデスクリプションの一節だった。
Lambda で動かすので、Lambda と同じ環境でコンパイルする必要があります。 Lambda 実行環境と利用できるライブラリ によると Amazon Linux を使っている (2019/02 時点) ことがわかるため、Amazon Linux のコンテナ上でコンパイルすることにします。
これで思い出した。前回はec2でwhlファイルを実行してレイヤーを作成したのだった。ephemのバージョン番号だけでなくどのOS用の配布パッケージファイルを使ったのかまでメモしておいて本当によかった。
レイヤーを作成するのに最初に参照したページが細かい部分でいろいろ説明不足だったり間違っていたりしたのが少々不運であった。新しく書かれたQuiitaの記事(1)(2)にはちゃんと書かれている。
さて、ephemはCコンパイラを含み、このコンパイラがpythonのマイナーバージョン毎に生成されるため、レイヤー作成環境と実行環境でpythonのバージョンを合わせなければならない。
PythonのLambda用レイヤーを公開・管理しているリポジトリがあり、有名どころは揃っている印象とのことだが、ephemはマイナーなライブラリなので残念ながら毎回自分で作ることになる。
なんとかpythonを3.12へバージョンアップし、仮想環境下でライブラリをインストールしたら、仮想環境でのpythonのバージョンは3.9のままで脱力してしまった。仮想環境のpythonのバージョンを上げるのは諦め、普通にフォルダを作ってそこにpip install。
めでたくレイヤーのバージョンアップが完了した。
【参考にしたサイト】
・【AWS Lambda】Pythonパッケージのレイヤー追加・関数での利用方法|No Module Namedエラー対策
・AWS Lambda で C のバイナリを動かす
・【初心者向け】AWS Lambda Layerの作成方法をわかりやすく解説【Python3.9】
・【AWS】Lambda関数のレイヤー作成と利用【Lambda】
・Lambda × Python で外部レイヤーを利用するときは Klayers が便利
・【AP Tech Blog Week】Amazon Linux 2023 でも Python 3.11.7 以上を使いたい
・Cloud9でPython3.12.xへバージョンアップする
・もっと気軽にpip install
・Lambda Layer にアップロードするための zip ファイルを作成するには Cloud9 環境を利用すると結構便利