ข้อผิดพลาดของโมดูลการนำเข้า AWS Lambda ใน python


93

ฉันกำลังสร้างแพ็คเกจการปรับใช้ AWS Lambda python ฉันกำลังใช้คำขอการอ้างอิงภายนอกหนึ่งรายการ ผมติดตั้งการพึ่งพาภายนอกโดยใช้เอกสาร AWS http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html ด้านล่างนี้คือรหัสหลามของฉัน

import requests

print('Loading function')

s3 = boto3.client('s3')


def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        s3.download_file(bucket,key, '/tmp/data.txt')
        lines = [line.rstrip('\n') for line in open('/tmp/data.txt')]
        for line in lines:
            col=line.split(',')
            print(col[5],col[6])
        print("CONTENT TYPE: " + response['ContentType'])
        return response['ContentType']
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e

สร้างไฟล์ Zip เนื้อหาของไดเร็กทอรี project-dir และอัปโหลดไปยังแลมบ์ดา (Zip เนื้อหาไดเร็กทอรีไม่ใช่ไดเร็กทอรี) เมื่อฉันเรียกใช้ฟังก์ชันฉันได้รับข้อผิดพลาดที่กล่าวถึงด้านล่าง

START RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058 Version: $LATEST
**Unable to import module 'lambda_function': No module named lambda_function**

END RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058
REPORT RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058  Duration: 19.63 ms  Billed Duration: 100 ms     Memory Size: 128 MB Max Memory Used: 9 MB

กรุณาช่วยฉันแก้ไขข้อผิดพลาด


รหัสเต็มของคุณหรือไม่ จากข้อผิดพลาดดูเหมือนว่ามีบางสิ่งที่ต้องการimport lambda_functionซึ่งไม่พบ บางทีคุณอาจต้องการfrom future import lambda_function? หรือเพียงแค่ติดตั้ง lambda_functionบนบรรทัด cmd
Berci

@Berci Am ใช้ python code ในแพลตฟอร์ม AWS นี้ ฉันไม่สามารถใช้ pip ที่ใดก็ได้ในรหัสของฉันกำลังใช้ lambda_function หากฉันคัดลอกวางรหัสเดียวกันในคอนโซล AWS มันจะใช้งานได้
Nithin K Anil

ดูความคิดเห็นล่าสุดในหัวข้อนี้ - อาจเกี่ยวข้องกับคุณ?
kwinkunks

@kwinkunks ฉันพยายามแล้ว กำลังซิปเนื้อหาไม่ใช่ไดเร็กทอรี !!
Nithin K Anil

2
ฉันเดาว่าตัวเลือก "ตัวจัดการ" ในฟังก์ชันของคุณไม่ถูกต้อง ตรวจสอบว่าชื่อไฟล์ของคุณเรียกว่า "lambda_function.py" และวิธีการจัดการคือ "lambda_handler"
Vor

คำตอบ:


110

ข้อผิดพลาดเกิดจากชื่อไฟล์ของฟังก์ชันแลมบ์ดา ในขณะที่สร้างฟังก์ชันแลมบ์ดาจะขอตัวจัดการฟังก์ชันแลมด้า คุณต้องมันเป็นชื่อที่คุณPython_File_Name.Method_Name ในสถานการณ์นี้ฉันตั้งชื่อมันเป็น lambda.lambda_handler (lambda.py คือชื่อไฟล์)

โปรดดูภาพรวมด้านล่าง ป้อนคำอธิบายภาพที่นี่


1
รหัสของฉันอยู่ในแลมบ์ดาเป็นรหัสไม่ใช่เป็นไฟล์
Ben Wheeler

4
@BenWheeler: แม้ว่าจะเป็นรหัสแบบอินไลน์ แต่ก็เป็นไฟล์ที่คุณเขียนขึ้นมา คุณสามารถดูชื่อไฟล์และโครงสร้างไดเร็กทอรีทั้งหมดทางด้านซ้ายของหน้าต่าง
Vineeth

ดังนั้นฉันจึงตั้งชื่อรหัสของฉันว่า "lambda_function.py" ฉันควรตั้งชื่อตัวจัดการเป็น Python_lambda_function.lambda_handler หรือไม่
RB17

@RahulBanerjee ไม่คุณจะเรียกมันว่า lambda_function.lambda_handler
Dinesh

91

หากคุณกำลังอัปโหลดไฟล์ zip ตรวจสอบให้แน่ใจว่าคุณกำลังบีบอัดเนื้อหาของไดเร็กทอรีไม่ใช่ไดเร็กทอรีเอง


3
เวลารูดซิปอย่าลืมใช้แฟล็ก -r ด้วย!
Grant Robert Smith

@ 2ank3th คุณดีที่สุด
Sethuraman Srinivasan

ขอบคุณสำหรับสิ่งนี้.
JamesG

24

สาเหตุอีกประการหนึ่งของปัญหานี้คือสิทธิ์ในไฟล์ที่ถูกบีบอัด มันจะต้องเป็นที่อ่านได้ทั่วโลกอย่างน้อย (นาทีchmod 444)

ฉันเรียกใช้สิ่งต่อไปนี้ในไฟล์ python ก่อนที่จะบีบอัดและทำงานได้ดี

chmod u=rwx,go=r

4
นี้. ฉันใช้ ZipFile ของ Python เพื่อจัดแพ็กเกจฟังก์ชันแลมบ์ดาลงใน ZIP โดยทางโปรแกรมมันเป็นค่าเริ่มต้นที่จะมี0600สิ่งที่คุณพูดถึงนั้นไม่เพียงพอ นอกจากนี้ตัวแก้ไขซอร์สโค้ด Lambda ในตัว (บนหน้าเว็บ Amazon) จะอ่านไฟล์อย่างมีความสุขโดยไม่มีคำเตือนเกี่ยวกับปัญหาการอนุญาต
cjhanks

2
ประการที่สอง. ฉันทำให้มันใช้งานได้โดยตั้งค่าการอนุญาตไฟล์โดยใช้วิธีการที่แสดงที่นี่: stackoverflow.com/a/434689/931277
dokkaebi

16

ฉันพบว่าคำตอบของ Nithin มีประโยชน์มาก นี่คือการเดินผ่านเฉพาะ:

ค้นหาค่าเหล่านี้:

  1. ชื่อของฟังก์ชัน lambda_handler ในสคริปต์ python ของคุณ ชื่อที่ใช้ในตัวอย่าง AWS คือ "lambda_handler" ซึ่งดูเหมือน "def lambda_handler (เหตุการณ์บริบท)" ในกรณีนี้ค่าคือ "lambda_handler"
  2. ในแดชบอร์ด Lambda ค้นหาชื่อของ Handler ในกล่องข้อความ "Handler" ในส่วน "Configuration" ในแดชบอร์ดแลมบ์ดาสำหรับฟังก์ชัน (แสดงในภาพหน้าจอของ Nithin) ชื่อเริ่มต้นของฉันคือ "lambda_function.lambda_handler"
  3. ชื่อสคริปต์ python ของคุณ สมมติว่าเป็น "cool.py"

ด้วยค่าเหล่านี้คุณจะต้องเปลี่ยนชื่อตัวจัดการ (ที่แสดงในภาพหน้าจอ) เป็น "cool.lambda_handler" นี่เป็นวิธีหนึ่งในการกำจัด errorMessage "Unable to import module 'lambda_function'" หากคุณจะเปลี่ยนชื่อตัวจัดการในสคริปต์ python ของคุณเป็น "sup" คุณจะต้องเปลี่ยนชื่อตัวจัดการในแดชบอร์ดแลมบ์ดาเป็น "cool.sup"


11

มีgotchaจำนวนมากเมื่อสร้างแพ็คเกจการปรับใช้สำหรับ AWS Lambda (สำหรับ Python) ฉันใช้เวลาหลายชั่วโมงในการแก้จุดบกพร่องจนกระทั่งพบสูตรที่ไม่ค่อยทำ

ฉันได้สร้างสคริปต์ที่ทำให้กระบวนการทั้งหมดเป็นไปโดยอัตโนมัติและทำให้เกิดข้อผิดพลาดน้อยลง ฉันยังเขียนบทช่วยสอนที่อธิบายวิธีการทำงานทุกอย่าง คุณอาจต้องการตรวจสอบ:

การปรับใช้ Python Lambda ที่ไม่ยุ่งยาก [บทช่วยสอน + สคริปต์]


2
โพสต์ที่ดี แต่ฉันพลาดรายละเอียดในส่วนที่ยากที่สุดซึ่งเป็นวิธีการจัดแพ็คเกจ libs ดั้งเดิม มันไม่ธรรมดาจริงๆที่ความซับซ้อนนี้
JohnAndrews

10

นี่เป็นขั้นตอนสั้น ๆ

สมมติคุณมีโฟลเดอร์ที่เรียกว่ามีแลมบ์ดาโทรแฟ้มที่อยู่ภายในของคุณdeploy lambda_function.pyสมมติว่าไฟล์นี้มีลักษณะดังนี้ ( p1และp2เป็นตัวแทนของแพ็คเกจของบุคคลที่สาม)

import p1
import p2

def lambda_handler(event, context):
    # more code here

    return {
        "status": 200,
        "body" : "Hello from Lambda!",
    }

สำหรับทุกการพึ่งพาของบุคคลที่สามคุณต้องpip install <third-party-package> --target .จากภายในdeployโฟลเดอร์

pip install p1 --target .
pip install p2 --target .

เมื่อคุณทำเสร็จแล้วโครงสร้างของคุณควรมีลักษณะดังนี้

deploy/
├── lambda_function.py
├── p1/
│   ├── __init__.py
│   ├── a.py
│   ├── b.py
│   └── c.py
└── p2/
    ├── __init__.py
    ├── x.py
    ├── y.py
    └── z.py

สุดท้ายคุณต้องนำzipเนื้อหาทั้งหมดภายในdeployโฟลเดอร์ไปยังไฟล์บีบอัด ใน Mac หรือ Linux คำสั่งจะดูเหมือนzip -r ../deploy.zip *จากในdeployโฟลเดอร์ โปรดสังเกตว่า-rแฟล็กมีไว้สำหรับโฟลเดอร์ย่อยแบบเรียกซ้ำ

โครงสร้างของไฟล์ zip ไฟล์ควรสะท้อนโฟลเดอร์เดิม

deploy.zip/
├── lambda_function.py
├── p1/
│   ├── __init__.py
│   ├── a.py
│   ├── b.py
│   └── c.py
└── p2/
    ├── __init__.py
    ├── x.py
    ├── y.py
    └── z.py

อัปโหลดไฟล์ zip และระบุ<file_name>.<function_name>สำหรับ Lambda เพื่อเข้าสู่กระบวนการของคุณเช่นlambda_function.lambda_handlerตัวอย่างด้านบน


1
นอกจากนี้อย่าซิปทั้งโฟลเดอร์เช่นzip -r deploy.zip deploy. สิ่งนี้จะสร้างโฟลเดอร์ปรับใช้ภายในไฟล์ zip
openwonk

9

ฉันพบวิธีที่ยากลำบากนี้หลังจากลองวิธีแก้ปัญหาทั้งหมดข้างต้น หากคุณใช้ไดเรกทอรีย่อยในไฟล์ zip ตรวจสอบให้แน่ใจว่าคุณได้รวม__init__.pyไฟล์ไว้ในไดเรกทอรีย่อยแต่ละรายการและใช้ได้กับฉัน


7

ฉันมีข้อผิดพลาดเกินไป ปรากฎว่าไฟล์ zip ของฉันมีโฟลเดอร์หลักของรหัส เมื่อฉันunzipและตรวจสอบไฟล์ซิปที่ไฟล์ที่อยู่ภายใต้โฟลเดอร์หลักlambda_function./lambda

ใช้zipคำสั่งแก้ไขข้อผิดพลาด:

zip -r ../lambda.zip ./*

1
เรียกใช้ zip ภายในโฟลเดอร์รหัสของคุณ กรณีของฉันที่นี่ cd lambda && zip -r ../lambda.zip ./*
โจ

4

ในรูปแบบที่จะต้องlambda_handler lambda_filename.lambda_functionNameหากว่าคุณต้องการที่จะเรียกใช้lambda_handlerฟังก์ชั่นและก็อยู่ในนั้นรูปแบบการจัดการของคุณlambda_fuction.pylambda_function.lambda_handler

อีกสาเหตุหนึ่งที่ทำให้เกิดข้อผิดพลาดนี้คือการขึ้นต่อกันของโมดูล

คุณlambda_fuction.pyต้องอยู่ในไดเรกทอรีรากของไฟล์ zip


2

@nithin, AWS เปิดตัวlayersแนวคิดภายในLambdaฟังก์ชัน คุณสามารถสร้างเลเยอร์ของคุณและคุณสามารถอัปโหลดได้มากถึงไลบรารีจากนั้นคุณสามารถเชื่อมต่อเลเยอร์ด้วยฟังก์ชันแลมบ์ดา สำหรับรายละเอียดเพิ่มเติม: https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html


2

มุมมองจากปี 2019:

ขณะนี้ AWS Lambda รองรับ Python 3.7 ซึ่งหลาย ๆ คน (รวมถึงตัวผมเอง) เลือกใช้เป็นรันไทม์สำหรับแลมบ์ดาแบบอินไลน์

จากนั้นฉันต้องนำเข้าการอ้างอิงภายนอกและฉันติดตาม AWS Docs ตามที่ OP อ้างถึง (ติดตั้งในเครื่อง -> zip -> อัพโหลด)

ฉันมีข้อผิดพลาดโมดูลการนำเข้าและฉันรู้ว่าพีซีในเครื่องของฉันมี Python 2.7 เป็น Python เริ่มต้น เมื่อฉันเรียกใช้ pip มันจะติดตั้งการอ้างอิงของฉันสำหรับ Python 2.7

ดังนั้นฉันจึงเปลี่ยนในเครื่องเป็นเวอร์ชัน Python ที่ตรงกับเวอร์ชันรันไทม์ที่เลือกในคอนโซลแลมบ์ดาแล้วติดตั้งการอ้างอิงภายนอกใหม่ สิ่งนี้ช่วยแก้ปัญหาให้ฉันได้ เช่น:

$ python3 -m pip install --target path/to/lambda_file <external_dependency_name>

1

ฉันพบปัญหาเดียวกันนี่เป็นแบบฝึกหัดซึ่งเป็นส่วนหนึ่งของบทช่วยสอนใน lynda.com ถ้าฉันไม่ผิด ข้อผิดพลาดที่ฉันทำคือไม่ได้เลือกรันไทม์เป็น Python 3.6 ซึ่งเป็นตัวเลือกในคอนโซลฟังก์ชัน lamda


1

ปัญหาที่ว่าเวอร์ชัน Python ที่ใช้สร้างการอ้างอิงฟังก์ชัน Lambda ของคุณ (บนเครื่องของคุณเอง) นั้นแตกต่างจากเวอร์ชัน Python ที่เลือกไว้สำหรับฟังก์ชัน Lambda ของคุณ กรณีนี้เป็นเรื่องปกติโดยเฉพาะอย่างยิ่งถ้าไลบรารี Numpy เป็นส่วนหนึ่งของการอ้างอิงของคุณ

ตัวอย่าง: เวอร์ชัน python ของเครื่องของคุณ: 3.6 ---> Lambda python เวอร์ชัน 3.6


0

คุณต้อง zip ข้อกำหนดทั้งหมดใช้สคริปต์นี้

#!/usr/bin/env bash
rm package.zip
mkdir package
pip install -r requirements.txt --target package
cat $1 > package/lambda_function.py
cd package
zip -r9 "../package.zip" .
cd ..
rm -rf package

ใช้กับ:

package.sh <python_file>

0

แบ่งปันวิธีแก้ปัญหาของฉันสำหรับปัญหาเดียวกันเผื่อว่าจะช่วยใครได้

ปัญหา: ฉันได้รับข้อผิดพลาด: "[ERROR] Runtime.ImportModuleError: ไม่สามารถนำเข้าโมดูล 'lambda_function': ไม่มีโมดูลชื่อ 'StringIO' ขณะเรียกใช้โค้ด aws-big-data-blog [1] ที่ให้ไว้ในบทความ AWS [2]

วิธีแก้ไข: เปลี่ยน Runtime จาก Python 3.7 เป็น Python 2.7

[1] - https://github.com/bsnively/aws-big-data-blog/blob/master/aws-blog-vpcflowlogs-athena-quicksight/CloudwatchLogsToFirehose/lambdacode.py [2] - https: // aws .amazon.com / blogs / big-data / analysis-vpc-flow-logs-with-amazon-kinesis-firehose-amazon-athena-and-amazon-quicksight /


มันเป็นอีกทางหนึ่งสำหรับฉัน (2.7 -> 3.8)
demonicdaron

0

คุณสามารถกำหนดค่าฟังก์ชัน Lambda ของคุณเพื่อดึงโค้ดและเนื้อหาเพิ่มเติมในรูปแบบของเลเยอร์ เลเยอร์คือไฟล์ ZIP ที่มีไลบรารีรันไทม์ที่กำหนดเองหรือการอ้างอิงอื่น ๆ ด้วยเลเยอร์คุณสามารถใช้ไลบรารีในฟังก์ชันของคุณได้โดยไม่จำเป็นต้องรวมไว้ในแพ็คเกจการปรับใช้ของคุณ เลเยอร์ช่วยให้คุณทำให้แพ็คเกจการปรับใช้งานของคุณมีขนาดเล็กซึ่งทำให้การพัฒนาง่ายขึ้น

อ้างอิง: -

  1. https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html
  2. https://towardsdatascience.com/introduction-to-amazon-lambda-layers-and-boto3-using-python3-39bd390add17


0

ปัญหาของฉันคือไฟล์. py และการอ้างอิงไม่ได้อยู่ในไดเร็กทอรี "root" ของ zip เช่นเส้นทางของไลบรารีและฟังก์ชันแลมบ์ดา. py ต้องเป็น:

<lambda_function_name>.py
<name of library>/foo/bar/

ไม่

/foo/bar/<name of library>/foo2/bar2

ตัวอย่างเช่น:

drwxr-xr-x  3.0 unx        0 bx stor 20-Apr-17 19:43 boto3/ec2/__pycache__/
-rw-r--r--  3.0 unx      192 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/__init__.cpython-37.pyc
-rw-r--r--  3.0 unx      758 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/deletetags.cpython-37.pyc
-rw-r--r--  3.0 unx      965 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/createtags.cpython-37.pyc
-rw-r--r--  3.0 unx     7781 tx defN 20-Apr-17 20:33 download-cs-sensors-to-s3.py

0

ไปที่โฟลเดอร์หลัก (แพ็คเกจการปรับใช้) ที่คุณต้องการ zip

ภายในโฟลเดอร์นั้นให้เลือกไฟล์ทั้งหมดจากนั้นสร้าง zip และอัปโหลดไฟล์ zip นั้น


0

กรุณาเพิ่มด้านล่างทีละรายการ Import requests

import boto3

สิ่งที่ฉันเห็นที่ขาดหายไปในรหัสของคุณ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.