首页 > 解决方案 > AWS Lambda /tmp python脚本导入模块错误

问题描述

我正在尝试运行 AWS Lambda /tmp 目录中存在的 python 脚本。这些脚本需要一些额外的依赖项,如 boto3 等来运行文件。当 AWS Lambda 运行该文件时,它会给出以下错误:

ModuleNotFoundError: No module named 'boto3'

但是,当我直接将此文件作为 lambda 函数运行时,它可以轻松运行而不会出现任何导入错误。

试图执行 /tmp 目录中的代码的 Lambda 代码:

import json
import os
import urllib.parse
import boto3
s3 = boto3.client('s3')


def lambda_handler(event, context):
    records = [x for x in event.get('Records', []) if x.get('eventName') == 'ObjectCreated:Put']
    sorted_events = sorted(records, key=lambda e: e.get('eventTime'))
    latest_event = sorted_events[-1] if sorted_events else {}
    info = latest_event.get('s3', {})
    file_key = info.get('object', {}).get('key')
    bucket_name = info.get('bucket', {}).get('name')
    s3 = boto3.resource('s3')
    BUCKET_NAME = bucket_name
    keys = [file_key]
    for KEY in keys:
        local_file_name = '/tmp/'+KEY
        s3.Bucket(BUCKET_NAME).download_file(KEY, local_file_name)
        print("Running Incoming File !! ")
        os.system('python ' + local_file_name)

尝试使用 boto3 从 S3 获取一些数据的 /tmp 代码:

import sys
import boto3
import json


def main():
    session = boto3.Session(
                aws_access_key_id='##',
                aws_secret_access_key='##',
                region_name='##')
                
    s3 = session.resource('s3')

    # get a handle on the bucket that holds your file
    bucket = s3.Bucket('##')

    # get a handle on the object you want (i.e. your file)
    obj = bucket.Object(key='8.json') 

    # get the object
    response = obj.get()

    # read the contents of the file
    lines = response['Body'].read().decode()
    data = json.loads(lines)
    transactions = data['dataset']['fields']
    print(str(len(transactions)))
    return str(len(transactions))

main()

所以 boto3 在两个代码中都被导入。但它只有在 lambda 代码执行时才成功。但是 /tmp 代码无法导入 boto3 。可能是什么原因,我该如何解决?

标签: amazon-web-servicesaws-lambda

解决方案


默认情况下,执行另一个 python 进程不会复制 Lambda 的 PYTHONPATH:

os.system('python ' + local_file_name)

像这样重写:

os.system('PYTHONPATH=/var/runtime python ' + local_file_name)

为了找出当前 Lambda 版本正在使用的完整 PYTHONPATH,请将以下内容添加到第一个脚本(由 Lambda 执行的脚本):

import sys
print(sys.path)

推荐阅读