AWS Lambda:无法导入模块“python_handler”:没有名为“_cffi_backend”的模块

问题描述 投票:0回答:6

当我需要读取 API 上的信息、创建 CSV 文件并将其上传到 SFTP 服务器时,我正在创建 AWS Lambda 函数。

我已经在我的 venv 上安装了 paramiko,在 Windows 上使用 Ubuntu,并且 cffi 模块就像一个依赖项,但是当代码运行时,我收到此错误:

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

按照我的代码操作:

import paramiko
import requests
from random import randrange
from datetime import datetime
from datetime import timedelta
from requests.auth import HTTPBasicAuth


def lambda_handler(event, context):
    # Lambda function
    addZero = lambda x : '0' + str(x) if x < 10 else str(x)

    # Actual datetime
    ac_yr = datetime.utcnow().year
    ac_mo = datetime.utcnow().month
    ac_da = datetime.utcnow().day
    ac_hh = datetime.utcnow().hour
    ac_mi = datetime.utcnow().minute
    ac_se = datetime.utcnow().second

    # 24 hours ago
    ag_yr = (datetime.utcnow() - timedelta(hours=24)).year
    ag_mo = (datetime.utcnow() - timedelta(hours=24)).month
    ag_da = (datetime.utcnow() - timedelta(hours=24)).day
    ag_hh = (datetime.utcnow() - timedelta(hours=24)).hour
    ag_mi = (datetime.utcnow() - timedelta(hours=24)).minute
    ag_se = (datetime.utcnow() - timedelta(hours=24)).second

    # API Infos
    api_key = 'XYZ'
    page_id = 'XYZ'

    # Call API
    param = {
        'sort_order': 'asc',
        'from': '{}-{}-{}T{}:{}:{}.000Z'.format(ag_yr, addZero(ag_mo), addZero(ag_da), addZero(ag_hh), addZero(ag_mi), addZero(ag_se)),
        'to': '{}-{}-{}T{}:{}:{}.000Z'.format(ac_yr, addZero(ac_mo), addZero(ac_da), addZero(ac_hh), addZero(ac_mi), addZero(ac_se))
    }
    r = requests.get('https://api.unbounce.com/pages/{}/leads'.format(page_id), auth=HTTPBasicAuth(api_key, 'pass'), params=param)

    # If connection it's ok
    if r.status_code == 200:
        # If has any result
        if len(r.json()['leads']) > 0:
            cont = ''
            for lead in r.json()['leads']:
                cont += lead['form_data']['cpf'][0] + ','
                cont += lead['form_data']['nome_completo'][0] + ','
                cont += lead['form_data']['email'][0]
        else:
            return 'Não há resultados no momento'
    else:
        return 'Falha na conexão'

    # Write a CSV file
    f = open('my_csv.csv','w')
    f.write('PAC_ID, PAC_NAME, PAC_EMAIL\n')
    f.write(cont)
    f.close()

    transport = paramiko.Transport(('host-info', 22))
    transport.connect(None, 'user-info', 'password-info', None)

    sftp = paramiko.SFTPClient.from_transport(transport)
    sftp.chdir('Import')
    sftpclient.put('my_csv.csv')

    return 'OK'

知道如何解决这个问题吗?

python aws-lambda sftp paramiko
6个回答
8
投票

当您的 AWS Lambda 函数的运行时版本与用于创建 Lambda 层的 Python 版本不同时,您也可能会收到错误

No module named '_cffi_backend'

当我将 Lambda 函数的运行时设置为 Python 3.10 时收到此错误,但我在运行 Python 3.8 的环境中安装了 Lambda 层的依赖项。


4
投票

最简单的解决方案是使用lambda容器,如此处所述。我在这里写了一些详细的内容。

简而言之,一些 Python 包(例如

cffi

)具有操作系统级别的依赖关系。由于您打包代码的操作系统与 Lambda 使用的操作系统不同,因此脚本无法运行。


3
投票
在 Ubuntu 上工作,我没有成功使用 pysftp 或 paramiko 到 Lambda。 因此,我在桌面上创建了一个 EC2 实例(在使用 Amazon Linux 2 的 VirtualBox 之后),并使用相同的库开发相同的代码。而且...这有效...


1
投票
可能会迟到,希望能对将来的人有所帮助。这个答案特定于“_cffi_backend......”。另一件可能有帮助的事情是了解你是如何安装 python 的。如果使用brew,您将需要使用python 创建一个虚拟环境。参见这里:

https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html

我在Linux环境中完成了此操作,没有下载与各种Linux发行版兼容的wheel文件,并且它有效


0
投票
这看起来是许多二进制包的常见问题。 我还没有通用的解决方案,但您真正要做的是将二进制文件从真正安装的位置移动(符号链接)到包的根目录。

我通常使用 Lambda 的安装后脚本来解决这个问题。使用

paramiko

 的运行类似:

ln -s venv/MY_LAMBDA/lib/python3.6/site-packages/_cffi_backend.cpython-36m-x86_64-linux-gnu.so MY_LAMBDA/ ln -s venv/MY_LAMBDA/lib/python3.6/site-packages/.libs_cffi_backend/libffi-XXXXXXXX.so.6.0.4 MY_LAMBDA/ ln -s venv/MY_LAMBDA/lib/python3.6/site-packages/nacl MY_LAMBDA/

您必须从 virtualenv 中识别

libffi...

 文件的确切名称。它可能与您编译库的机器不同。


0
投票
使用

serverless

 cli 和 
serverless-python-requirements
 插件,如果您更改 AWS Lambda python 运行时版本并发布,该插件将使用与旧 python 版本相同的 pip 下载缓存。 (此缓存位于您的 git 存储库之外,因此 
git clean
 也没有帮助。)

这会导致 lambda 中包含

_cffi_backend.cpython-310-x86_64-linux-gnu.so

,即使您希望使用 
cpython-311

修复方法是运行

serverless requirements cleanCache

 删除 pip 下载缓存。

© www.soinside.com 2019 - 2024. All rights reserved.