首页 > 解决方案 > 在 AWS Lambda 中安装 Python 包?

问题描述

我正在尝试在 AWS Lambda 函数中安装一个包。

Amazon 推荐的方法是创建一个包含依赖项和 python 函数的压缩部署包(如Python 中的 AWS Lambda 部署包中所述)。但是,这会导致无法使用 AWS Lambda GUI 中的内联代码编辑来编辑 Lambda 函数。

所以相反,我想在 AWS Lambda 函数本身内安装包。在 AWS Lambda 中,除了 /tmp/ 目录之外,文件系统是只读的,因此我尝试将 pip install 安装到 /tmp/ 目录。该函数每天只调用一次,因此我不介意每次运行该函数时重新安装软件包所需的额外几秒钟。

我的尝试

def lambda_handler(event, context):
    # pip install dependencies
    print('begin lambda handler')
    import subprocess
    import sys
    subprocess.call('pip install cryptography -t /tmp/ --no-cache-dir'.split())
    from cryptography.fernet import Fernet
    pwd_encrypted = b'gAAAAABeTcT0OXH96ib7TD5-sTII6jMfUXPhMpwWRCF0315rWp4C0yav1XAPIn7prfkkA4tltYiWFAJ22bwuaj0z1CKaGl8vTgNd695SDl25HnLwu1xTzaQ='
    key = b'fP-7YR1hUeVW4KmFmly4JdgotD6qjR52g11RQms6Llo='
    cipher_suite = Fernet(key)
    result = cipher_suite.decrypt(pwd_encrypted).decode('utf-8')
    print(result)
    print('end lambda handler')

但是,这会导致错误

[错误] ModuleNotFoundError:没有名为“密码学”的模块

我也尝试用以下内容替换子进程调用,如this stackoverflow answer中所建议的那样

    cmd = sys.executable+' -m pip install cryptography -t dependencies --no-cache-dir'
    subprocess.check_call(cmd.split())

但是,这会导致错误

OSError:[Errno 30] 只读文件系统:'/var/task/dependencies'

标签: python-3.xaws-lambdapip

解决方案


我通过对原始尝试的单行调整解决了这个问题。您只需将 /tmp/ 添加到 sys.path 以便 Python 知道在 /tmp/ 中搜索该模块。您需要做的就是添加该行sys.path.insert(1, '/tmp/')

解决方案

import os
import sys
import subprocess

# pip install custom package to /tmp/ and add to path
subprocess.call('pip install cryptography -t /tmp/ --no-cache-dir'.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
sys.path.insert(1, '/tmp/')
from cryptography.fernet import Fernet

def lambda_handler(event, context):
    # pip install dependencies
    pwd_encrypted = b'gAAAAABeTcT0OXH96ib7TD5-sTII6jMfUXPhMpwWRCF0315rWp4C0yav1XAPIn7prfkkA4tltYiWFAJ22bwuaj0z1CKaGl8vTgNd695SDl25HnLwu1xTzaQ='
    key = b'fP-7YR1hUeVW4KmFmly4JdgotD6qjR52g11RQms6Llo='
    cipher_suite = Fernet(key)
    result = cipher_suite.decrypt(pwd_encrypted).decode('utf-8')
    print(result)

输出

你好堆栈溢出!

注意 - 正如评论中提到的@JohnRotenstein,添加 Python 包的首选方法是在AWS Lambda 层中打包依赖项。我的解决方案只是表明可以直接在 AWS Lambda 函数中安装包。


推荐阅读