Tidak dapat mengimpor modul 'lambda_function': Tidak ada modul bernama *

Oct 12 2020

Saya mencoba menjalankan fungsi lambda python yang menggunakan paket tambahan. Namun setiap kali saya mengunggah file .zip ke konsol lambda, saya mendapatkan kesalahan:

{
  "errorMessage": "Unable to import module 'lambda_function': No module named '*'",
  "errorType": "Runtime.ImportModuleError"
}

Saya mengikuti instruksi ini: https://docs.aws.amazon.com/lambda/latest/dg/python-package.html#python-package-dependencies yang memberi tahu saya untuk memastikan paket saya berada di direktori lokal ke fungsi lambda saya:

~/my-function$ pip install --target ./package Pillow

Saya tidak menggunakan Bantal. Ini adalah contoh kode dari situs mereka. Saya juga tidak menggunakan paket yang sudah dapat Anda akses di Lambda. Ini adalah salah satu yang saya dapatkan dari github dan perlu dilampirkan ke aplikasi saya.

Pada awalnya ini tidak berhasil jadi saya membuat setup.cfgfile dan menambahkan:

[install]
prefix= 

Sekarang, ketika saya menggunakan pipperintah untuk menginstal ke target, itu berfungsi (dan juga menambahkan banyak folder lain selain paket saya tetapi saya berasumsi mereka diperlukan jadi saya meninggalkannya di sana.

Ketika saya masuk ke direktori, paketnya ada di sana.

Saya kemudian menemukan jawaban ini: https://stackoverflow.com/a/12493244/5675125 yang menyarankan mungkin beberapa file tersembunyi tidak disertakan dan ini adalah cara saya membuat zip.

Sekali lagi kesalahan yang sama.

Bagaimana cara membuat lambda mengenali bahwa paket saya ada di sana.

Jawaban

1 Marcin Oct 12 2020 at 10:28

Jika Anda membutuhkan Pillow, cara termudah untuk menggunakannya dalam fungsi Anda adalah melalui repositori populer dengan layer publik (termasuk bantal) seperti keithrozario / Klayers di github. Untuk menggunakannya, Anda akan menemukan ARN dari lapisan berdasarkan wilayah Anda . Daftar ARN untuk python 3.8 ada di sini .

Misalnya, untuk us-east-1lapisan yang ditambahkan untuk Python 3.7 adalah:

Memperbarui

Saya baru saja membuat lapisan khusus dengan instabotdan dapat mengonfirmasi bahwa itu berfungsi.

Teknik yang digunakan termasuk alat buruh pelabuhan yang dijelaskan dalam blog AWS terbaru :

  • Bagaimana cara membuat lapisan Lambda menggunakan lingkungan Lambda yang disimulasikan dengan Docker?

Jadi untuk pertanyaan ini, saya memverifikasi sebagai berikut:

  1. Buat folder kosong, mis mylayer.

  2. Buka folder dan buat requirements.txtfile dengan konten

instabot
  1. Jalankan perintah buruh pelabuhan berikut:
docker run -v "$PWD":/var/task "lambci/lambda:build-python3.8" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.8/site-packages/; exit"
  1. Hapus numpy

The instabotmemerlukan numpyyang sangat besar. Jadi kami menghapusnya secara manual, sebelum membuat lapisan. Kami akan menggunakan numpylapisan yang disediakan oleh AWS sebagai gantinya.

sudo rm -rvf ./python/lib/python3.8/site-packages/numpy*

Jika kita tidak menghapus numpy, layer akan menjadi> 50MB.

  1. Buat lapisan sebagai zip:
zip -9 -r mylayer.zip python 
  1. Buat lapisan lambda berdasarkan mylayer.zipdi Konsol AWS. Jangan lupa untuk menentukan Compatible runtimeske python3.8.

  2. Tambahkan dua lapisan ke fungsi Anda:

Yang pertama AWSLambda-Python38-SciPy1xdisediakan oleh AWS dengan numpy, sedangkan yang kedua adalah yang kita buat di atas. Jadi fungsi Anda akan menggunakan dua lapisan.

  1. Uji lapisan di lambda menggunakan fungsi lambda berikut:
import json

from instabot import Bot

def lambda_handler(event, context):
    # TODO implement
    
    bot = Bot(base_path='/tmp')
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }