layersディレクトリの中に、hello_layerというものがあり、これをLambdaから読み込みたい。
1 2 3 4 5 |
layers └── hello_layer ├── hello.py └── module1 └── module1.py |
hello.pyで、 module1ディレクトリ内のmodule1.pyを読み込みたいわけだけれど、通常のpythonの相対インポートの書き方だとどうもうまくいかない。
だめな例
1 |
from .module1 import module1_handler |
うまくいく例
1 2 3 4 5 6 7 8 |
from module1.module1 import module1_handler def function_hello(): print("Hello World Layer!") print("----------") module1_handler() print("----------") |
module1.py
1 2 3 |
def module1_handler(): print('hello module1') return |
Lambda本体側の書き方。
通常のZip形式かImage形式かで、layerのインポート方法が変わる。
通常のZip形式の場合
Lambdalayerは/opt/pythonディレクトリにマウントというかコピーされ、PATHが通っている状態。
なので、hello.pyのファイル名のhelloをimportすれば良い。
1 2 3 4 5 6 7 |
import hello def lambda_handler(event, context): print("Hello World") print("-------------") hello.function_hello() |
Image形式の場合
Dockerfileをこのように書く
ここでミソなのは、layerを/opt/pythonディレクトリに配置するところ。
Zip形式と同様に、/opt/pythonディレクトリにPATHが通っており、このディレクトリに配置しておくことで、モジュール名で読み込めるようになる。
1 2 3 4 5 6 7 8 9 |
FROM public.ecr.aws/lambda/python:3.10 COPY ./hello_world/app.py ./hello_world/requirements.txt ./ COPY ./layers/hello_layer /opt/python RUN python3.10 -m pip install -r requirements.txt -t . # Command can be overwritten by providing a different command in the template directly. CMD ["app.lambda_handler"] |
app.pyはZip形式と同じ
1 2 3 4 5 6 7 |
import hello def lambda_handler(event, context): print("Hello World") print("-------------") hello.function_hello() |