Lỗi mô-đun nhập AWS Lambda trong python


92

Tôi đang tạo gói triển khai python AWS Lambda. Tôi đang sử dụng một yêu cầu phụ thuộc bên ngoài. Tôi đã cài đặt phần phụ thuộc bên ngoài bằng cách sử dụng tài liệu AWS http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html . Dưới đây là mã python của tôi.

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

Tạo Zip nội dung của thư mục project-dir và tải lên lambda (Zip nội dung thư mục, không phải thư mục). Khi tôi thực thi chức năng, tôi gặp lỗi được đề cập bên dưới.

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

Vui lòng giúp tôi gỡ lỗi.


Nó có phải là mã đầy đủ của bạn không? Bởi lỗi có vẻ như ở đâu đó một cái gì đó sẽ muốn import lambda_functionmà không được tìm thấy. Có lẽ bạn muốn from future import lambda_function? Hoặc chỉ cần pip cài đặt lambda_ Chức năng trên dòng cmd.
Berci

@Berci Am đang chạy nền tảng AWS codein python này. Tôi không thể sử dụng pip. bất cứ nơi nào trong mã của tôi đang sử dụng lambda_ Chức năng. NẾU tôi sao chép dán đoạn mã tương tự trong AWS an ủi nó sẽ làm việc
Nithin K Anil

Xem bình luận cuối cùng về chủ đề này - có thể áp dụng cho bạn?
kwinkunks

@kwinkunks Tôi đã thử điều đó. Trên thực tế tôi đang nén nội dung không phải là thư mục !!
Nithin K Anil

2
Tôi đoán là tùy chọn "xử lý" trong hàm của bạn không chính xác. Kiểm tra xem tên tệp của bạn có tên là "lambda_osystem.py" và phương thức xử lý là "lambda_handler" hay không
Vor

Câu trả lời:


110

Lỗi do tên tệp của hàm lambda. Trong khi tạo hàm lambda, nó sẽ yêu cầu trình xử lý hàm Lambda. Bạn phải đặt tên nó là Python_File_Name.Method_Name của bạn . Trong trường hợp này, tôi đặt tên nó là lambda.lambda_handler (lambda.py là tên tệp).

Vui lòng tìm ảnh chụp nhanh bên dưới. nhập mô tả hình ảnh ở đây


1
Mã của tôi chỉ ở dạng mã lambda - không phải dưới dạng tệp.
Ben Wheeler

4
@BenWheeler: Mặc dù nó là mã nội tuyến, nó là một tệp bạn thực sự viết nó. Bạn có thể thấy tên tệp và toàn bộ cấu trúc thư mục ở bên trái cửa sổ.
Vineeth

Vì vậy, tôi đã đặt tên mã của mình là "lambda_ Chức năng.py", tôi có nên đặt tên trình xử lý là Python_lambda_ Chức năng.lambda_handler không?
RB17

@RahulBanerjee Không. Bạn sẽ gọi nó là lambda_ Chức năng.lambda_handler
Dinesh

90

Nếu bạn đang tải lên một tệp zip. Đảm bảo rằng bạn đang nén nội dung của thư mục chứ không phải chính thư mục đó.


2
Khi nén, hãy đảm bảo rằng bạn cũng đang sử dụng cờ -r!
Grant Robert Smith

@ 2ank3th bạn là người tốt nhất
Sethuraman Srinivasan

Cám ơn vì cái này.
JamesG

24

Một nguồn khác của vấn đề này là quyền trên tệp được nén. Nó phải ít nhất có thể đọc được trên toàn thế giới. (phút chmod 444)

Tôi đã chạy phần sau trên tệp python trước khi nén nó và nó hoạt động tốt.

chmod u=rwx,go=r

4
Điều này. Tôi đang sử dụng ZipFile của Python để lập trình đóng gói các hàm lambda vào ZIP, nó mặc định có 0600như bạn đề cập là không đủ. Hơn nữa, trình soạn thảo mã nguồn Lambda tích hợp (trên trang web Amazon) sẽ vui vẻ đọc tệp mà không cần cảnh báo về các vấn đề về quyền.
cjhanks

2
Thứ hai. Tôi đã làm cho nó hoạt động bằng cách đặt quyền đối với tệp bằng phương pháp được hiển thị ở đây: stackoverflow.com/a/434689/931277
dokkaebi

15

Tôi thấy câu trả lời của Nithin rất hữu ích. Dưới đây là một hướng dẫn cụ thể:

Tra cứu các giá trị sau:

  1. Tên của hàm lambda_handler trong tập lệnh python của bạn. Tên được sử dụng trong các ví dụ AWS là "lambda_handler" trông giống như "def lambda_handler (sự kiện, ngữ cảnh)". Trong trường hợp này, giá trị là "lambda_handler"
  2. Trong bảng điều khiển Lambda, hãy tìm tên của Trình xử lý trong hộp văn bản "Trình xử lý" trong phần "Cấu hình" trong bảng điều khiển lambda cho chức năng (được hiển thị trong ảnh chụp màn hình của Nithin). Tên mặc định của tôi là "lambda_ Chức năng.lambda_handler".
  3. Tên của tập lệnh python của bạn. Giả sử đó là "cool.py"

Với các giá trị này, bạn sẽ cần đổi tên trình xử lý (được hiển thị trong ảnh chụp màn hình) thành "cool.lambda_handler". Đây là một cách để loại bỏ thông báo lỗi "Không thể nhập mô-đun 'lambda_ Chức năng'". Nếu bạn đã đổi tên trình xử lý trong tập lệnh python của mình thành "sup" thì bạn cần đổi tên trình xử lý trong bảng điều khiển lambda thành "cool.sup"


11

Có rất nhiều chỉ gotchas khi tạo các gói triển khai cho AWS Lambda (đối với Python). Tôi đã dành hàng giờ đồng hồ cho các phiên gỡ lỗi cho đến khi tôi tìm thấy một công thức hiếm khi bị lỗi.

Tôi đã tạo một tập lệnh tự động hóa toàn bộ quy trình và do đó làm cho nó ít bị lỗi hơn. Tôi cũng đã viết hướng dẫn giải thích cách mọi thứ hoạt động. Bạn có thể muốn kiểm tra nó:

Triển khai Python Lambda một cách dễ dàng [Hướng dẫn + Tập lệnh]


2
Bài đăng tuyệt vời nhưng tôi bỏ lỡ chi tiết về phần khó nhất là cách đóng gói các lib bản địa. Nó thực sự không bình thường như thế nào phức tạp này là
JohnAndrews

10

Đây là một bước nhanh chóng.

Giả sử bạn có một thư mục được gọi deploy, với tệp lambda của bạn bên trong cuộc gọi lambda_function.py. Giả sử tệp này trông giống như thế này. ( p1p2đại diện cho các gói của bên thứ ba.)

import p1
import p2

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

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

Đối với mọi phụ thuộc của bên thứ ba, bạn cần phải pip install <third-party-package> --target .từ bên trong deploythư mục.

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

Khi bạn đã hoàn thành việc này, đây là cấu trúc của bạn sẽ trông như thế nào.

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

Cuối cùng, bạn cần chuyển ziptất cả nội dung trong deploythư mục vào một tệp nén. Trên máy Mac hoặc Linux, lệnh sẽ giống như zip -r ../deploy.zip *trong deploythư mục. Lưu ý rằng -rcờ dành cho các thư mục con đệ quy.

Cấu trúc của tệp zip tệp phải sao chép thư mục gốc.

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

Tải lên tệp zip và chỉ định <file_name>.<function_name>Lambda để tham gia vào quy trình của bạn, chẳng hạn như lambda_function.lambda_handlerví dụ ở trên.


1
Ngoài ra, KHÔNG nén toàn bộ thư mục như zip -r deploy.zip deploy. Thao tác này sẽ tạo một thư mục triển khai trong tệp zip.
openwonk

9

Tôi đã tìm thấy cách này khó khăn sau khi thử tất cả các giải pháp ở trên. Nếu bạn đang sử dụng các thư mục con trong tệp zip, hãy đảm bảo bạn đưa __init__.pytệp vào từng thư mục con và điều đó phù hợp với tôi.


7

Tôi cũng có lỗi. Hóa ra rằng tệp zip của tôi bao gồm thư mục mẹ mã. Khi tôi unzipvà kiểm tra tệp zip, lambda_functiontệp nằm trong thư mục mẹ ./lambda.

Sử dụng ziplệnh, sửa lỗi:

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

1
chạy mã zip bên trong thư mục mã của bạn. trường hợp của tôi ở đây, cd lambda && zip -r ../lambda.zip ./*
Joe

4

Trong lambda_handlerđịnh dạng phải được lambda_filename.lambda_functionName. Giả sử bạn muốn chạy lambda_handlerhàm và nó ở trong lambda_fuction.py, thì định dạng trình xử lý của bạn là lambda_function.lambda_handler.

Một lý do khác để nhận được lỗi này là sự phụ thuộc của mô-đun.

Của bạn lambda_fuction.pyphải ở trong thư mục gốc của tệp zip.



1

Tôi đã gặp phải vấn đề tương tự, đây là một bài tập như một phần của hướng dẫn trên lynda.com nếu tôi không sai. Sai lầm tôi đã thực hiện là không chọn thời gian chạy là Python 3.6, là một tùy chọn trong bảng điều khiển hàm lamda.


1

Một góc nhìn từ năm 2019:

AWS Lambda hiện hỗ trợ Python 3.7, được nhiều người (bao gồm cả tôi) chọn sử dụng làm thời gian chạy cho lambdas nội tuyến.

Sau đó, tôi phải nhập phụ thuộc bên ngoài và tôi theo dõi AWS Docs như OP đã đề cập. (cài đặt cục bộ -> zip -> tải lên).

Tôi đã gặp lỗi mô-đun nhập và tôi nhận ra rằng PC cục bộ của mình có Python 2.7 làm Python mặc định. Khi tôi gọi pip, nó đã cài đặt phần phụ thuộc của tôi cho Python 2.7.

Vì vậy, tôi đã chuyển cục bộ sang phiên bản Python phù hợp với phiên bản thời gian chạy đã chọn trong bảng điều khiển lambda và sau đó cài đặt lại các phụ thuộc bên ngoài. Điều này giải quyết các vấn đề đối với tôi. Ví dụ:

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

1

Vấn đề ở đây là phiên bản Python được sử dụng để xây dựng phần phụ thuộc hàm Lambda của bạn (trên máy của riêng bạn) khác với phiên bản Python đã chọn cho hàm Lambda của bạn. Trường hợp này thường xảy ra đặc biệt nếu thư viện Numpy là một phần của các phụ thuộc của bạn.

Ví dụ: Phiên bản python trên máy của bạn: 3.6 ---> Lambda python phiên bản 3.6


0

Bạn cần nén tất cả các yêu cầu, sử dụng tập lệnh này

#!/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

dùng với:

package.sh <python_file>

0

Chia sẻ giải pháp của tôi cho cùng một vấn đề, đề phòng nó có ích cho bất kỳ ai.

Sự cố: Tôi gặp lỗi: "[ERROR] Runtime.ImportModuleError: Không thể nhập mô-đun 'lambda_ Chức năng': Không có mô-đun nào có tên 'StringIO'" trong khi thực thi mã aws-big-data-blog [1] được cung cấp trong bài viết AWS [2].

Giải pháp: Đã thay đổi thời gian chạy từ Python 3.7 sang 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 /


Đối với tôi thì ngược lại (2,7 -> 3,8)
demonicdaron

0

Bạn có thể định cấu hình hàm Lambda của mình để lấy thêm mã và nội dung dưới dạng các lớp. Lớp là một kho lưu trữ ZIP có chứa các thư viện, thời gian chạy tùy chỉnh hoặc các phần phụ thuộc khác. Với các lớp, bạn có thể sử dụng các thư viện trong chức năng của mình mà không cần đưa chúng vào gói triển khai. Lớp cho phép bạn giữ cho gói triển khai của mình nhỏ, giúp phát triển dễ dàng hơn.

Người giới thiệu:-

  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

Vấn đề của tôi là tệp .py và các phụ thuộc không có trong thư mục "gốc" của zip. ví dụ: đường dẫn của các thư viện và hàm lambda .py phải là:

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

không phải

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

Ví dụ:

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

Trên thực tế, hãy chuyển đến thư mục chính (gói triển khai) mà bạn muốn nén,

Bên trong thư mục đó, chọn tất cả các tệp, sau đó tạo tệp nén và tải tệp nén đó lên


0

Vui lòng thêm bên dưới một sau Import requests

import boto3

Những gì tôi có thể thấy bị thiếu trong mã của bạn.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.